c# – 语句的不可到达端点(不可达端点)是什么?

灵感来自这个问题的答案

Is empty case of switch in C# combined with the next non-empty one?

该术语的唯一出现在C#语言规范的§6.5中

  • If D has a non-void return type and the body of F is a statement block, when each parameter of F is given the type of the corresponding parameter in D, the body of F is a valid statement block (wrt §8.2) with a non-reachable end point in which each return statement specifies an expression that is implicitly convertible to the return type of D.

我们可以看到规范中的后期

  • 8.1 End points and reachability

    Every statement has an end point. In intuitive terms, the end point of a statement is the location that immediately follows the statement. The execution rules for composite statements (statements that contain embedded statements) specify the action that is taken when control reaches the end point of an embedded statement. For example, when control reaches the end point of a statement in a block, control is transferred to the next statement in the block.

我们可能会有一些感觉.但是,我用Google搜索并发现没有直接解释不可到达的端点.因为Stack Overflow是一个Q& A站点,我认为如果有一个更简单和更直观的解释,可以轻松搜索和理解这个术语将有助于程序员,特别是那些不是母语为英语的人.

最佳答案 Ben的回答很好地理解了它.为了更精确,终点:

>休息
>继续
>转到
>回归
>扔

语句无法访问.这些语句中的每一个都在“结束之前”将控制转移到其他地方,因此语句的“终点”永远不会被命中.将其与以下语句进行比较:

> Console.WriteLine();
>我;

等等,将控制转移到下一个语句.

循环提出了一个有趣的挑战:

while(x) { M(); }

这基本上与:

BEGIN: 
if (!x) goto END;
{ M(); }
goto BEGIN;
END: ;

所以端点是可达的.但

while(true) { M(); }

可以优化为:

BEGIN: 
{ M(); }
goto BEGIN;

由于现在无法“到达目的地”,因此该语句被认为具有无法到达的终点.要么永远循环,要么M()永远不会返回,或者M()抛出;无论哪种方式,都没有达到声明的终点.

确定可达性的确切规则比这个草图要复杂一些,但是这可以让你对它们有所了解. (我喜欢让人们看看他们是否掌握了可达性的挑战是:编写一个程序,该程序具有可访问的goto语句但相应的标记语句是无法访问的.Tricky!)

这些规则在许多地方使用.立即想到三个:首先,开关部分必须没有可达到的终点.其次,非void的方法(或lambda或属性getter等)必须没有可到达的端点.第三,如果方法具有可到达的终点并且它具有out参数,则必须在结束点明确指定参数.

点赞