关于c#:检测到无法访问的代码(为什么?)

Unreachable Code Detected (Why?)

所以,为什么在这段代码中检测到无法访问的代码:

1
2
3
4
5
6
7
8
9
10
      public bool GetKeyPressed(KeyCode key)
    {
        for (int i = 0; i < keys.Count; i++)
            if (keys[i].key == key && keys[i].pressed)
                return true;
            else
                return false;

        return false;
    }

索引(i)显然无法访问…为什么?


您的代码有一个循环计算一次,因此第一次迭代将始终返回。

如果这就是你想要的,就这么说吧,

1
return keys[0].key == key && keys[0].pressed;

但是,如果(这是我在这里怀疑的),如果数组中的任何一个满足您的测试,您希望返回true,那么使用linq的Any()

1
return keys.Any(k => k.key == key && k.pressed);


扩展JDphenix的答案,我认为我们需要理解为什么您的循环"评估一次",只有这样我们才能理解为什么存在"不可访问的代码"。

1
2
3
4
5
6
7
8
9
10
public bool GetKeyPressed(Keys key)
{
    for (int i = 0; i < keys.Count; i++)
        if (keys[i].key == key && keys[i].pressed)
            return true;
        else
            return false;

    return false;
}

for循环有一个组成主体的if-else语句。if保护如果满足返回true,否则执行下一个返回falseelse语句。最终的结果是,不管keys中的项数是多少,在控制返回到调用方法之前,最多执行一个循环。

更明显的是,如果我们通过JetBrains Resharper查看代码:

enter image description here

代码也可以写为:

1
2
3
4
5
6
7
8
9
10
public bool GetKeyPressed(Keys key)
{
    for (int i = 0; i < keys.Count; ) // Look Ma, no i++  !!!
        if (keys[i].key == key && keys[i].pressed)
            return true;
        else
            return false;

    return false;
}

不要误以为方法末尾的最后一个return false不是必需的,因为它是在keys.Count == 0的场景中。

enter image description here

当然,对代码进行更好的格式设置会很长一段时间,从而揭示出第一个return false是多余的,可以根据un lucky的答案进行简化:

enter image description here


您的代码有两条代码路径,一条是通过if条件,另一条是通过else条件。这意味着控制将以这两种方式离开功能。所以else之后的返回语句永远不会触发。这就是编译器将其作为不可访问代码的原因。这可以通过使用以下代码来避免。

1
2
3
4
5
6
7
public bool GetKeyPressed(KeyCode key)
{
    for (int i = 0; i < keys.Count; i++)
        if (keys[i].key == key && keys[i].pressed)
            return true;          
        return false;
}