【问题标题】:Visual Studio marks code just after "case variable:" unreachableVisual Studio 在“case variable:”之后标记代码无法访问
【发布时间】:2015-10-23 09:56:30
【问题描述】:

我有一个包含多种情况的 switch 语句:

ConversionState state = ConversionState.Start; // enum
for(int i = 0; i < source.Length; i ++)
{
    switch(state)
    {
        case ConversionState.Start:
            state = ConversionState.Name; // <-- warning here
            name += source[i]; // source is a string
            break;
        case ConversionState.Name:
            if(source[i] == ' ') // <-- warning here
            {
                name = name.ToLower();
                if(name[0] == '/')
                    name = name.SubString(1);
                state = ConversionState.Between;
            }
            else
                name += source[i];
            break;
        case ConversionState.Between: // no code in this case statement, yet to be implemented
            break; // <-- warning here
    }
}

我在三个标记的行上收到警告:“检测到无法访问的代码”。案例之后的第一个语句不能无法访问,不是吗?我的问题是:

  1. 是我的代码有问题,还是警告有误?

  2. 如果 VS2015 认为代码 sn-p 无法访问,当我在优化编译时它会被删除吗?如果没有,我应该忽略这个警告吗?

  3. 此警告是否意味着标记的行不可达,或者整个案例不可达?

PS:我知道当前的代码可以在没有 switch 的情况下重写,这会解决问题,但是将来添加的代码将使它 - 非常 - 更容易使用 switch 来维护。

编辑(由 amit dayama 要求):

private enum ConversionState
{
  Start, Between, Name, Argument, Switch
}

枚举位于具有包含原始发布代码的方法的类中。

编辑 2: 此代码所在方法的第一行是throw new NotImplementedException();。显然,这使得 Visual Studio 将方法中每个 switch 中每个 case 的第一行标记为不可访问,但没有其他内容,而且有趣的是,不是异常之后的整个代码。

【问题讨论】:

  • 请粘贴更多代码。不能在我的机器上复制(VS 2015)。
  • 你能显示你的枚举吗?
  • ConversionState state = ConversionState.Start; 在这里您明确设置了状态,因此开关总是只执行第一种情况。
  • @LocEngineer,在第一次运行 for 循环时为 state 分配 ConversionState.Name。
  • 请发布枚举的定义。也许有重叠的值或标志?

标签: c# switch-statement visual-studio-2015 unreachable-code


【解决方案1】:

我已经检查了您的代码,并且所有内容都使用 VS2012 在我这边编译和构建。我现在VS2015有一些问题,错误列表窗口中有很多误报。

所以问题 1:在我看来,您的代码是正确的。

问题 2:不完全确定,但相信 id 不会将其删除以进行优化。我可能是错的,但警告的原因是您解决了它而不是编译器。当我为你找到正确答案时,我会添加评论。

问题 3:一行不是整个案例。

PS:也许您可以尝试将花括号添加到您的一些 if 和 else 语句中。我知道它们不是一个衬垫所必需的,但它们可能会导致 VS2015 中的特定行为

【讨论】:

  • 谢谢。如果代码优化没有消除它,我想我可以忍受那 3 个额外的警告。
  • 是的,您很可能会接受它。这取决于开发人员。很可能会在 VS2015 的下一个补丁中得到修复,如果这就是问题的根源。
【解决方案2】:

您将在switch 语句中手动检查的变量设置为ConversionState.Start

这很简单,因为在switch 语句之前没有代码可以改变它,Visual Studio 会将其他情况标记为无法访问的代码。

如果我没记错的话,Visual Studio(或您使用的插件?)看不到用于switch 语句的变量在这种情况下正在被更改,从而引发警告。 并回答其余问题

如果 VS2015 认为代码 sn-p 无法访问,是否将其删除 当我进行优化编译时?如果没有,我应该忽略 这个警告?

据我所知,警告就是警告。它不会干扰代码的最终结果。它会警告您可能有问题。

此警告是否意味着标记的行无法到达,或者 整个案子都达不到?

整个案例都无法到达。在这种情况下,控制流永远不会得到,所以里面的所有代码都不会被执行。

编辑在代码审查方面,您的代码确实令人困惑。您使用特定案例来运行 source 集合中的第 0 个元素。为什么不在第 0 个元素上执行该代码并从下一个元素开始循环?

【讨论】:

  • 感谢您的指出,我将删除 Start 并将其放在 for 循环之前或将其与 Name 合并。我没有 15 名声望,所以如果我支持一个答案,就看不到它,但把它当作我支持它。
  • @sisisisi 你现在有:-P
【解决方案3】:

这对我来说似乎很奇怪。 首先,我不知道 ConversationState 的属性是什么。 如果它来自 Lync API,则属性似乎错误,实际是 Active、Parked、Inactive 和 Terminated。

所以我会做一个这样的开关盒

ConversionState state = ConversationState.Active;
for(int i = 0; i < source.Length; i ++)
{
  switch(state)
  {
    case ConversationState.Active:
      state = ConversionState.Name; 
      name += source[i]; 
      break;
    case ConversationState.Inactive:
      if(source[i] == ' ') 
      {
        name = name.ToLower();
        if(name[0] == '/')
          name = name.SubString(1);
        state = ConversionState.Between;
      }
      else
        name += source[i];
      break;
}

问题似乎您使用的案例形式错误。如果我错了,请纠正我。

【讨论】:

  • 这是ConversionState,而不是ConversationState。此外,OP 的 case 语法没有任何问题。编辑:很好,我本来也来自特里尔;)
猜你喜欢
  • 1970-01-01
  • 2023-03-28
  • 2020-08-15
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 2014-01-29
  • 1970-01-01
  • 2020-06-01
相关资源
最近更新 更多