【发布时间】:2017-09-01 01:29:23
【问题描述】:
示例代码:
switch(something)
{
case 0:
System.Environment.Exit(0);
case 1:
// blah ...
break;
}
它不会编译,因为编译器认为执行可以从 Exit() 返回。编译器明显错了。
没有技巧。 System.Environment.Exit() 是真的。
System.Environment.Exit() 返回不仅完全不合逻辑,而且我追踪了代码,它最终调用了无法返回的ExitProcess(exitCode);。
【问题讨论】:
-
由于编译器无法查看方法的 IL 来了解运行时将执行什么(因为编译器绝对无法知道运行时将加载的确切程序集), 你如何建议编译器知道给定的方法永远不会返回?
-
@AlexeiLevenkov:鉴于目前的情况,[System.Runtime.InteropServices.NoReturn] void Exit(int ExitCode);如果我重新写这个,会有一个类型(类似于 System.Void)意味着无法访问。
-
属性不是方法签名的一部分 - 所以它不会工作,因为编译器不能保证在运行时加载的库实现该方法甚至会有属性(忽略编译器的事实并且 JIT 将不得不以某种方式强制执行该属性的行为)。确实,作为方法签名一部分的返回特殊类型会起作用,但是是否值得构建整个额外的基础设施来验证该方法不能为这种终止进程的方法的特殊情况返回?
-
@AlexeiLevenkov: function(out x) 撒谎。 out 实际上是
[System.Runtime.InteropServices.Out]。它不是那么特殊的目的;任何保证抛出的方法都可以用这个标记;还要注意 C 和 C++ 有它。如果调用缺少它的运行时库,代码甚至不会加载,所以这是一个小问题。 -
编译器只遵循specification:如果 expression_statement 可达,则 expression_statement 的端点是可达的。
标签: c# compiler-errors design-rationale