C# 类方法。如何失败并返回为什么?

标签 c# .net error-handling

我确信有一种“好”的方法可以解决这个问题,但它一直困扰着我。我有一个方法应该返回一个对象,但它的参数有一定的先决条件。这些不在我的控制范围内,可能会因“业务逻辑”原因而失败(如果你能原谅这个陈旧的术语)。

对象的返回值将为空,但我也想回传原因,因此调用代码基本上可以说“我没有取回我的对象​​,因为没有足够的信息来构建它”。

我不觉得 try catch 是正确的方法,但一直在这种情况下使用它,因为需要更好的方法。我在 stackoverflow 和教科书以及 MSDN 上的所有阅读似乎都集中在何时或如何使用异常上,但我不知何故未能为这种情况提出一种方法。

谁能建议一种更合适的模式? (第一篇文章所以......请原谅任何失礼)

这是我一直在玩的示例:(注意//TODO 注释下方的 throw new Exception 行)

public static Packet Parse(string packetString)
{
    Packet returnPacket = new Packet();
    StringBuilder output = new StringBuilder();

    try
    {
        using (XmlReader reader = XmlReader.Create(new StringReader(packetString)))
        {
            XmlWriterSettings ws = new XmlWriterSettings();
            ws.Indent = true;
            using (XmlWriter writer = XmlWriter.Create(output, ws))
            {
                string rootNodeString = string.Empty;

                // Parse the packet string and capture each of the nodes.
                while (reader.Read())
                {
                    //test root node is the correct opening node name
                    if (rootNodeString == string.Empty)
                    {
                        if (reader.NodeType != XmlNodeType.Element || reader.Name != PACKETROOT)
                        {
                            // TODO: I don't really think this should be an exception, but going with it for now for expediency, since XmlReader is doing the same anyway
                            throw new Exception(string.Format("The root node of a Packet must be <{0}>", PACKETROOT));
                        }
                        else
                        {
                            rootNodeString = reader.Name;
                        }
                    }

                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            Console.WriteLine(string.Format("start element = {0}", reader.Name));
                            break;
                        case XmlNodeType.Text:
                            Console.WriteLine(string.Format("text = {0}", reader.Value));
                            break;
                        case XmlNodeType.XmlDeclaration:
                        case XmlNodeType.ProcessingInstruction:
                            Console.WriteLine(string.Format("XmlDeclaration/ProcessingInstruction = {0},{1}", reader.Name, reader.Value));
                            break;
                        case XmlNodeType.Comment:
                            Console.WriteLine(string.Format("comment = {0}", reader.Value));
                            break;
                        case XmlNodeType.EndElement:
                            Console.WriteLine(string.Format("end element = {0}", reader.Name));
                            break;
                    }
                }

            }
        }

    }
    catch (XmlException xem)
    {
        Console.WriteLine(xem.Message);
        throw;
    }

    return returnPacket;
}

最佳答案

I have a method that is supposed to return an object, but has certain preconditions for its parameters. These are outside my control and can fail for "business logic" reasons



如果前提确实是 前提条件那么不遵守前提条件的调用者就会出现错误。正确的做法是让被调用者抛出一个异常,理想情况下是一个积极地使整个进程崩溃的异常。这将强烈鼓励调用者修复他们的错误。

但是根据您的描述,听起来您所拥有的实际上并不是先决条件;先决条件是必须为真的事情,如果它们不总是正确的,那么调用者就是错误的。听起来你所拥有的是一种做得太多的方法;它既验证所提供的参数是否被某些业务策略归类为有效,并且在参数有效时计算结果。

因此,我倾向于将其分为两种方法。

第一种方法分析其参数以查看业务策略是否将它们归类为有效,并返回详细描述参数有效或无效原因的报告对象。

第二种方法计算结果。第二种方法可以将第一种方法验证参数作为其先决条件。

The return value of the object would be null but I'd also like to pass back why, so the calling code can essentially say "I didn't get my object back because there wasn't enough information to build it".



再一次,这更多地证明你试图做的太多了。您希望该方法的返回值同时是 分析 描述不满足业务规则的原因,以及 结果 的业务流程。这是两个非常不同的东西,因此应该通过两种不同的方法来计算。

关于C# 类方法。如何失败并返回为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9006712/

相关文章:

c# - 用于唯一标识节点的最佳集合是什么?

javascript - 解析AngularJS客户端错误

r - 错误: could not find function … in R

c# - 在 PropertyGrid 中动态设置属性的只读属性

c# - WPF HTTPWebRequest 底层连接已关闭 : An unexpected error occurred on a receive

ruby-on-rails - 在 OSX 上安装 Ruby 1.9.2 时遇到问题 - Readline 和 Make 错误

c# - 有没有比使用 WhenAnyValue 和 BindTo 更好的方法来设置读写属性?

c# - 方法名中使用 "Async"后缀是否取决于是否使用 'async'修饰符?

c# - 由于登录 Pop3 的意外数据包格式导致握手失败

c++ - 创建可在大多数 PC 上运行的 C++ 程序