我想不出一个好的头衔,但我的问题并不像它看起来那么幼稚.
考虑一下:
public static void ExitApp(string message)
{
// Do stuff
throw new Exception(...);
}
Run Code Online (Sandbox Code Playgroud)
要么
public static void ExitApp(string message)
{
// Do stuff
System.Environment.Exit(-1);
}
Run Code Online (Sandbox Code Playgroud)
这些方法都不会回归.但是当你在别处调用这些方法时:
public int DoStuff()
{
// Do stuff
if (foo == 0)
{
throw new Exception(...);
}
else if (foo == 1)
{
// Do other stuff
return ...;
}
else
{
ExitApp("Something borked");
}
}
Run Code Online (Sandbox Code Playgroud)
尝试编译它,你会在DoStuff中得到一个"并非所有代码路径都返回一个值".使用Exception来跟踪对ExitApp的调用似乎很愚蠢,只是为了满足编译器,即使我知道它很好.在ExitApp()中似乎没有任何东西可以表明它永远不会返回.
如何向编译器指示ExitApp永远不会返回,因此,DoStuff的else块也永远不会返回? 这似乎是一个相当简单的错误,它的路径检查无法解释.
即使我只使用第一个ExitApp(抛出异常)并且该方法返回一个int,路径检查器足够聪明,意识到它永远不会返回,所以它不会抱怨int类型.这个编译文件:
public static int ExitApp(string message)
{
// Do stuff
throw new Exception(...);
}
Run Code Online (Sandbox Code Playgroud)
但是,鉴于它知道这个ExitApp永远不会返回一个int,它不会将它推断到DoStuff()所以我倾向于认为我的问题没有解决方案.我唯一的选择是在调用ExitApp之后抛出异常.
public int DoStuff()
{
...
else
{
ExitApp("Something borked");
throw new NotImplementedException("Should not reach this");
}
}
Run Code Online (Sandbox Code Playgroud)
编译器有这种行为的原因吗?
Cra*_*ney 12
我为此目的定义了一个异常:UnreachableException.这看起来似乎是多余的,但这是一种简单的方式来说"嘿,读这个的人,这行不应该被执行!".我通常将它用于某些switch语句的默认情况,但它也适用于此处.
只需在ExitApp行之后抛出一个.
public void int DoStuff()
{
// Do stuff
if (foo == 0)
{
throw new Exception(...);
}
else if (foo == 1)
{
// Do other stuff
return ...;
}
else
{
ExitApp("Something borked");
throw new UnreachableException();
}
}
Run Code Online (Sandbox Code Playgroud)
语言不支持声明一个总是抛出的方法的实际原因只是:它不值得.语言开发人员没有无限的时间来应用我们能想到的每个功能.他们必须优先考虑.
我敢打赌这是你第一次遇到这种情况,看看:明确抛出异常处理问题.他们为什么要费心处理这种罕见的,容易绕过的情况呢?他们可能会花时间实现可选参数,动态或其他一些更有用的东西,并且比能够说函数总是抛出异常更频繁地使用.
这并不是说它永远不会被实施.这种类型的方法信息正是合同在指定时非常好的类型.所以它可能会包含在代码合同中.