2017-09-01 47 views
-1

示例代码:为什么编译器认为Environment.Exit可以返回?

switch(something) 
{ 
    case 0: 
     System.Environment.Exit(0); 
    case 1: 
     // blah ... 
     break; 
} 

它不能编译,因为编译器认为该执行可以从出口返回()。编译器显然是错误的。

没有窍门。 System.Environment.Exit()是真正的。

不仅对于System.Environment.Exit()返回是完全不合逻辑的,我追溯了代码,最终调用了ExitProcess(exitCode);,它不能返回。

+0

由于编译器无法查看方法的IL以知道在运行时将执行什么(因为编译器绝对没有办法知道在运行时将装载什么精确的程序集),您将如何*建议编译器知道给定的方法不会返回? –

+0

@AlexeiLevenkov:鉴于目前的情况,[System.Runtime.InteropServices.NoReturn] void Exit(int ExitCode);如果我重新写这个,会有一个类似于System.Void的类型,意味着无法访问。 – Joshua

+0

属性不是方法签名的一部分 - 所以它不起作用,因为编译器不能保证在运行时加载库来实现该方法甚至会拥有该属性(忽略编译器和JIT必须强制执行的事实莫名其妙)。事实上,返回特殊类型是方法签名的一部分,但它是否值得构建整个额外基础结构,以验证该方法无法返回此方法终止进程的特殊情况? –

回答

6

就语言而言,它可以返回。是的,在现实生活中,过程将在它有机会返回之前终止,但编译器不知道基于方法签名。

您需要在其中添加“break”以使编译器很高兴。

+0

这个答案很难解释到底是什么问题。这几乎就像是在回答什么,而不是为什么。 – Joshua

+0

想象一下你有一个名为'Foo'的方法,它叫做System.Environment.Exit()。你会期望'switch'语句强制你在调用'Foo()'后调用'break',或者你希望switch语句通过检查它的代码路径来理解'Foo'的含义以知道它会终止该过程并不能返回? – Tim

+0

编译器不应该依赖库调用的副作用。这个特殊的调用不能保证工作,它可以抛出异常。 –

相关问题