我发现自己编写了一些方法,其中存在一个永远不会发生的代码路径。这是一个简化的例子:
double Foo(double x) {
int maxInput = 100000;
double castMaxInput = (double)maxInput;
if (x < 0 || x > castMaxInput || double.IsNaN(x)) {
return double.NaN;
}
double r = 0;
for (double boundary = 1; boundary<=castMaxInput; boundary++) {
if (x <= boundary) {
r += boundary * (x + 1 - boundary);
return r;
}
else {
r += boundary;
}
}
// we should never get here.
throw new SomeException();
}
这里最有意义的例外是
TheAuthorOfThisMethodScrewedUpException()
因为如果我们到达for循环的末尾,那就是正在发生的事情。不幸的是,使用上面构造的方法,编译器似乎不够聪明,无法确定for循环之后的代码永远不会发生。所以你不能在那里什么也没有,或者编译器会抱怨“并非所有的代码路径都返回一个值”。是的,除了之前我还可以在循环之后输入return double.NaN
。但这会掩盖问题的根源。
我的问题是 - 是否存在适当的例外情况?
答案 0 :(得分:8)
我使用InvalidOperationException
class。这意味着应用程序已达到不应该处于的状态。
throw new InvalidOperationException("Invalid state.");
你也可以Debug.Assert
表示某事是真的,或者只是Debug.Fail
当执行到达特定点时。
Debug.Fail("This should never happen!");
但是,只有在定义DEBUG
条件时,调试断言/失败才能在发布模式下工作。取决于您的要求是否合乎需要。
作为@AlexD correctly points out,还有Trace
class及其相应的Assert
和Fail
方法,它们将在运行时中运行,以帮助隔离和修复问题在定义TRACE
条件时(默认情况下在“项目属性构建”选项卡中设置),不会干扰正在运行的系统。
顺便说一句,要回答标题中的问题:如果需要,可以创建自己的例外。
[Serializable]
public class TheAuthorOfThisMethodScrewedUpException : InvalidOperationException
{
private const string DefaultMessage = "The author of this method screwed up!";
public TheAuthorOfThisMethodScrewedUpException()
: this(DefaultMessage, null)
{ }
public TheAuthorOfThisMethodScrewedUpException(Exception inner)
: base(DefaultMessage, inner)
{ }
public TheAuthorOfThisMethodScrewedUpException(string message)
: this(message, null)
{ }
public TheAuthorOfThisMethodScrewedUpException(string message, Exception inner)
: base(message, inner)
{ }
protected TheAuthorOfThisMethodScrewedUpException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context)
{ }
}
把它扔给别人。
throw new TheAuthorOfThisMethodScrewedUpException();
答案 1 :(得分:2)
不要抛出新的Exception(),它会导致代码尝试捕获异常时出现问题。您可以使用的通用特定异常是:
throw new InvalidOperationException("Appplication invariants violated");
这假设你希望在生产中发生错误,假设错误比发射导弹和结束世界更好。其他开发人员宁愿使用一种方法,假设在生产中可以忽略不变量,但在开发时不能忽略,如果我们结束这个世界,我们就不在乎。
答案 2 :(得分:1)
public class TheAuthorOfThisMethodScrewedUpException: Exception
{
public EmployeeListNotFoundException()
{
}
public EmployeeListNotFoundException(string message)
: base(message)
{
}
public EmployeeListNotFoundException(string message, Exception inner)
: base(message, inner)
{
}
}
然后
throw new TheAuthorOfThisMethodScrewedUpException("I am so sorry, this should never happen call me for more info")
答案 3 :(得分:0)
轻松!使用代码段!
例外+ TAB + TAB
它会为你创造一个新的例外。这个片段产生了这个。
[Serializable]
public class MyException : Exception
{
public MyException() { }
public MyException(string message) : base(message) { }
public MyException(string message, Exception inner) : base(message, inner) { }
protected MyException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
您只需要更改名称和..完成! ;)