【问题标题】:c# switch problemc#切换问题
【发布时间】:2009-12-27 16:28:48
【问题描述】:

我是编程新手,对以下代码有疑问:

    private string alphaCoords(Int32 x)
    {
        char alphaChar;

        switch (x)
        {
            case 0: alphaChar = 'A'; break;
            case 1: alphaChar = 'B'; break;
            case 2: alphaChar = 'C'; break;
            case 3: alphaChar = 'D'; break;
            case 4: alphaChar = 'E'; break;
            case 5: alphaChar = 'F'; break;
            case 6: alphaChar = 'G'; break;
            case 7: alphaChar = 'H'; break;
            case 8: alphaChar = 'I'; break;
            case 9: alphaChar = 'J'; break;
        }

        return alphaChar.ToString();
    }

编译器说:使用未分配的局部变量'alphaChar'

但我在我的 switch 块中分配它。

我确定这是我的错,因为我对编程不够了解。

请指教。

谢谢。

【问题讨论】:

  • 另外,请注意:如果愿意,您可以输入 int 而不是 Int32。他们是同义词

标签: c# switch-statement unassigned-variable


【解决方案1】:

您正在分配它如果 x 是 0-9。如果x 是 123,你希望它做什么?虽然 可能知道只会传入 0 到 9 之间的值,但编译器不会 - 所以 需要考虑否则会发生什么。

避免这种情况的一种方法是在您的 switch 语句中使用 default 大小写,如果值不在预期范围内,您可以使用它来引发异常:

switch (x)
{
    case 0: alphaChar = 'A'; break;
    case 1: alphaChar = 'B'; break;
    case 2: alphaChar = 'C'; break;
    case 3: alphaChar = 'D'; break;
    case 4: alphaChar = 'E'; break;
    case 5: alphaChar = 'F'; break;
    case 6: alphaChar = 'G'; break;
    case 7: alphaChar = 'H'; break;
    case 8: alphaChar = 'I'; break;
    case 9: alphaChar = 'J'; break;
    default: throw new ArgumentOutOfRangeException();
}

这里有一个稍微简单的替代方案,它完全删除了你的 switch 语句:

if (x < 0 || x > 9)
{
    throw new ArgumentOutOfRangeException();
}
char alphaChar = (char)('A' + x);

请注意,您在使用这样的算术时确实需要小心。在 Java 和 C# 中,底层表示保证为 Unicode,这让生活变得更加轻松。我相信这样的事情(和十六进制解析/格式化)很好,但是当你冒险进入更奇特的场景时,它会失败。话又说回来,很多代码简化技术都是如此……如果应用不当,最终会变得一团糟。

【讨论】:

  • 但编译器不知道这一点,它无法验证或确保这一点。
  • 对 (char)('A' + x) 投反对票。在 Unicode 世界中,使用算术来操作字符值是一种非常糟糕的做法。
  • @Cylon Cat:在一个不受限制的范围内,我同意 - 但这里我们已经确定了 x 的值范围,并且结果明确定义。这种“非常糟糕的做法”是怎样的?你认为这段代码会出现什么问题?您能指出结果未定义或不正确的任何情况吗? 粗心算术与字符数据是一个坏主意,和所有这样的算术是一个坏主意之间有很大的区别。
  • @Jon,“在限制范围内”,是的,它有效。我担心的是建立坏习惯,以及对底层表示的特征的依赖。不过,我想到了两个直接案例。首先,这是一种仅限英语的技术;带有重音、变音符号等的语言需要避免这种情况。其次,我在 EBCDIC 长大,即使是基本的英文字母也不在一个连续的范围内('A'-'J' = xC0 到 xC9;'K'-'T' = xD0 到 xD9;'U-Z' = xE0 到 xE5)。所以一般来说,我信任指针算术胜过我信任字符算术,而且我不信任指针算术。
  • @Cylon Cat:但正如你所说,我们生活在“Unicode 世界”——所以你完全可以依赖算术将做什么(在 C# 和 Java 中)。您可以依赖底层表示,因为它是明确指定的。关于重音的业务与此代码无关,因为只需要考虑 A-J。我将在答案中添加一个注释,以警告尝试广泛应用此too,但对于这种特定情况,我对此毫无疑虑。
【解决方案2】:

编译器抱怨是因为 alphaChar 可能未定义——如果它不是您的switch 中的值之一,那么它就不会被定义。您可以执行以下操作之一:

  • 设置 char 的初始值,如果没有任何切换条件为真,将执行该值。
  • 在您的 switch 语句中添加一个“默认”子句。

【讨论】:

    【解决方案3】:

    在首次使用之前,必须明确分配局部变量(根据 C# 规范规则)。在这种特殊情况下,switch 构造不能保证肯定会分配 alphaChar,因此会出现编译器错误。您可以为 alphaChar 提供初始值,因此它肯定会被分配。

    【讨论】:

      【解决方案4】:

      你需要为你的 switch 语句添加一个默认值。

      编译器说明在某些情况下不会为变量赋值。所以加了

      default:
        alphaChar = 'x'
      break;
      

      会告诉编译器“所以如果我错过了一些场景,就把这个值设为这个”

      或者在不想指定默认值的情况下:

        default: throw new Exception();
      

      这不一定更好,而是另一种方式:

       private string alphaCoords(Int32 x)
          {
            if(x >= 0 && x =< 9)
                 return ((char)(x + 65)).ToString();
            else
              throw new ArgumentException();
          }
      

      【讨论】:

      • 我不想添加默认值,因为值只能从 0 到 9。
      【解决方案5】:

      您正在根据某些条件为变量alphaChar 赋值。想象一个场景,变量x包含0到9以外的值。假设它包含10。那么x将不满足任何case条件,因此alphaChar不会被分配任何值,结果它将完全未初始化。因此,当您将alphaChar 转换为字符串时,它会将一些垃圾值转换为字符串并将其返回给调用方法。这就是您收到该消息的原因。

      如果你想得到一个简单的解决方案,那么在下面添加以下代码

      case 9: alphaChar = 'J'; 
              break; 
      

      -

      default: return null;
      

      并在调用方法中检查这个alphaCoords函数是否返回null,像这样 -

      if(alphaCooord(10) == null)
      {
          // x contains value other than 0 to 9
      }
      else
      {
          // x contains value between 0 to 9, so the returned value will be the string
          // representation of the corresponding character
      }
      

      这样你的代码不会太复杂,或者你不需要抛出或处理任何异常或类似的东西。

      希望对您有所帮助:)。

      【讨论】:

        【解决方案6】:

        编译器无法知道变量 x 最多只能包含 9 的数字(这是您在 switch 中检查的数字)。由于您的开关中缺少default 大小写,因此可能会发生alphaChar 仍未分配。您可以添加 default 大小写或在 switch 之前为变量赋值。

        【讨论】:

          【解决方案7】:

          为您的开关添加一个默认值,因为如果 x 为 10,则永远不会分配 alphaChar。

          【讨论】:

            【解决方案8】:

            在声明变量 char alphaChar 后,您应该为其“赋值”(将其设置为等于某个值),即使您希望它在 switch 语句中获得一个值。

            您可以将其分配为“A”或“0”或几乎任何东西。

            你可以像这样在声明中这样做

            char alphaChar = 'A';
            

            或者你可以单独做

            char alphaChar;    
            alphaChar = 'A';
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-12-31
              • 1970-01-01
              相关资源
              最近更新 更多