【发布时间】:2009-05-07 18:32:32
【问题描述】:
我想不出一个好的标题,但我的问题并不像看起来那么幼稚。
考虑一下:
public static void ExitApp(string message)
{
// Do stuff
throw new Exception(...);
}
或
public static void ExitApp(string message)
{
// Do stuff
System.Environment.Exit(-1);
}
这些方法都不会返回。但是当你在别处调用这些方法时:
public int DoStuff()
{
// Do stuff
if (foo == 0)
{
throw new Exception(...);
}
else if (foo == 1)
{
// Do other stuff
return ...;
}
else
{
ExitApp("Something borked");
}
}
尝试编译它,您将在 DoStuff 中得到“并非所有代码路径都返回值”。尽管我知道很好,但为了满足编译器的要求,用异常跟踪对 ExitApp 的调用似乎很愚蠢。 ExitApp() 中似乎没有任何东西可以表明它永远不会返回。
我如何向编译器表明 ExitApp 永远不会返回,因此 DoStuff 的 else 块也永远不会返回? 这似乎是一个相当简单的错误,它的路径检查无法解决。
即使我只使用第一个 ExitApp(抛出异常)并且该方法返回一个 int,路径检查器也足够聪明,可以意识到它永远不会返回,因此它不会抱怨 int 类型。这个编译文件:
public static int ExitApp(string message)
{
// Do stuff
throw new Exception(...);
}
但是,鉴于它知道这个 ExitApp 永远不会返回一个 int,它不会将它外推到 DoStuff() 所以我倾向于相信我的问题没有解决方案。我唯一的选择是在调用 ExitApp 后抛出异常。
public int DoStuff()
{
...
else
{
ExitApp("Something borked");
throw new NotImplementedException("Should not reach this");
}
}
编译器有这种行为的原因吗?
【问题讨论】:
-
你真的是指 DoStuff 方法中的“void int”吗?
-
“有什么原因吗?”没有有用的答案。问题。无论哪种方式——好的理由,坏的理由,没有理由——你都被编译器困住了。您的这部分问题没有可操作的答案。
-
S.Lott,如果我忽略了代码的执行,它会阻止路径检查器知道 ExitApp 不会退出,从而知道DoStuff 很好。它不需要主观的答案。
-
原因是CLR类型系统没有“这个方法永远不会返回”的任何表示。由于 CLR 无法表示这一点,因此编译器无法推断具有该属性的调用。 “void”在CLR中已经是一个很特殊的类型,只能在方法的返回类型中使用。 CLR 团队可以添加另一种非常特殊的类型,“从不”。他们没有。如果他们这样做了,那么我们可以让编译器利用它。
-
Eric,但编译器当然明白我的“int ExitApp()”方法没有返回,也没有抱怨。
标签: c# compilation