gpt4 book ai didi

language-agnostic - 使用异常进行流量控制

转载 作者:行者123 更新时间:2023-12-02 22:18:03 25 4
gpt4 key购买 nike

最近有人告诉我,我正在滥用异常来控制应用程序中的流程,因此我试图以某种方式澄清这种情况。

在我看来,当方法遇到无法在内部处理的情况或调用方可能会更好处理的情况时,它应该抛出异常。

<小时/>

那么 - 是否存在任何特定的规则集,这些规则可用于在开发应用程序时回答以下问题集:

  • 什么时候应该抛出异常,什么时候应该编写带有强无抛出保证的代码,这可能简单地返回 bool表明成功还是失败?

  • 当方法抛出异常时,我应该尽量减少情况的数量,还是相反,应该最大化它以在处理这些情况时提供灵 active ?

  • 我应该坚持由我在开发应用程序时使用的框架/运行时设置的异常抛出约定,还是应该包装所有这些调用以便它们符合我自己的异常抛出策略吗?

  • 我还建议使用错误代码进行错误处理,这似乎非常有效,但从语法的角度来看很丑陋(而且,当使用它们时,开发人员失去了指定方法的输出)。对此您有何看法?

<小时/>

第三问题的示例(我使用 I/O 框架并遇到以下情况):

The described framework does not use exceptions to handle errors, but the other code does use them. Should I wrap every possible failure indicated with '???' and throw an exception in this case? Or should I change the signature of my method to bool
PrepareTheResultingOutputPath
and only indicate whether the operation was successful or not?

public void PrepareTheResultingOutputFile(
String templateFilePath, String outputFilePath)
{
if (!File.Exists(templateFilePath))
// ???

if (!Directory.MakePath(outputFilePath))
// ???

if (File.Exists(outputFilePath))
if (!File.Remove(outputFilePath))
// ???

if (!File.Copy(templateFilePath, outputFilePath)
// ???
}
<小时/>

另一个示例 - 即使.NET Framework也不遵循某些严格的异常抛出策略。一些方法被记录为抛出 10 多种不同的异常类型,包括像 NullArgumentException 这样的简单异常类型,但其中一些方法只是返回 bool 来指示操作的成功或失败。/p>

谢谢!

最佳答案

异常的问题在于它们本质上是美化的 goto,能够展开程序的调用堆栈。因此,如果您“使用异常进行流量控制”,那么您可能将它们用作 goto 而不是异常条件的指示。这正是异常(exception)的要点,也是其名称的原因:它们应该仅在异常(exception)情况中使用。因此,除非某个方法被设计为不引发异常(例如 .NET 的 int.TryParse),否则可以在异常情况下引发异常。

与 Java 相比,C# 的优点在于,在 C# 中,您基本上可以通过返回元组类型或使用输出参数来返回两个或多个值。因此,返回错误代码作为方法的主要返回值并没有太多丑陋之处,因为您可以使用 out 参数来完成其余的操作。例如,调用 int.TryParse 的常见范例是

string s = /* Read a string from somewhere */;
int n;
if (int.TryParse(s, out n))
{
// Use n somehow
}
else
{
// Tell the user that they entered a wrong number
}

现在回答你的第三个问题,这似乎是最重要的。引用您的示例代码,您询问是否应该返回 bool 来指示成功/失败,或者是否应该使用异常来指示失败。不过,还有第三种选择。您可以定义一个枚举来告诉方法如何失败,并将该类型的值返回给调用者。然后,调用者有一个广泛的选择:调用者不必使用一堆 try/catch 语句,也不必使用 if 来了解方法如何失败,但可以选择编写其中之一

if (PrepareTheResultingOutputFile(templateFilePath, outputFilePath) == Status.Success)
// Do something
else
// It failed!

switch (PrepareTheResultingOutputFile(templateFilePath, outputFilePath))
{
case Status.Success:
// Do something
break;
case Status.FileNotPresent:
// Do something else
break;
case Status.CannotMakePath:
// Do something else
break;
// And so on
default:
// Some other reason for failure
break;
}

您可以找到有关此问题的更多信息 herehere ,但尤其是在 Joel Spolsky's post 中,我强烈推荐。

关于language-agnostic - 使用异常进行流量控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9306913/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com