switch语句中的变量初始化问题

时间:2012-12-20 15:33:28

标签: c# .net language-agnostic switch-statement

我所拥有的是简单的开关语句

Control myControl;
switch(x)
{
     case TabType.Edit:
     {
         myControl= ...;
     }

     case TabType.View:
     {

         myControl= ...;
     }
 }

 myPageView.Controls.Add(myControl);

在这种情况下编译器告诉我

  

在访问

之前,可能无法初始化局部变量myControl

那么,避免这种情况的最佳方法是什么?

一个选项是在switch语句之前初始化myControl。但在这种情况下,我再做一次不必要的初始化。

案例1:

Control myControl = null;
switch(x)
{
     case TabType.Edit:
     {
         myControl= ...;
     }

     case TabType.View:
     {

         myControl= ...;
     }
 }

 myPageView.Controls.Add(myControl);

下一个选项是使用default更改第二个案例。之后,编译器将“理解”myControl无论如何都将被初始化并且不会抛出异常。

案例2:

Control myControl;
switch(x)
{
     case TabType.Edit:
     {
         myControl= ...;
     }

     default:
     {

         myControl= ...;
     }
 }

 myPageView.Controls.Add(myControl);

但是这种情况看起来并不那么好,因为在我的枚举中添加了一些新属性后,它会对所有其他类型执行默认操作(开发人员很容易忘记在此处更改代码,或者可能没有必要为其他类型初始化myControl枚举类型)。

在这种情况下,最佳方法是什么?

5 个答案:

答案 0 :(得分:6)

您的代码示例表明您将始终在切换块后使用myControl变量。如果是这种情况,那么您应该预先初始化变量,或者添加default子句(如您所述)。

如果您担心可能会引入新的枚举值,那么您可以在default子句中抛出一个有意义的异常。当您稍后尝试取消引用该变量时,这将保护您不会出现更加模糊的NullReferenceException

答案 1 :(得分:3)

第三个选项:在继续之前验证实例已创建(而不是依赖于它被分配):

Control mycontrol = null;
switch (x){
  // ...
}
if (myControl != null){
  // add to controls list, manipulate, etc.
}

您还可以将default:后果案例添加到default(TabType)值:

switch (x){
  case TabType.Two:
    // ...
  case TabType.Three:
    // ...
  case TabType.One:
  default:
    // ..
}

答案 2 :(得分:2)

我认为default专门针对这些情况而存在。

在我的枚举中添加一些新属性,它将对所有其他类型执行默认

它将允许您的代码在默认前提下工作(抛出异常或设置为众所周知的值),因此您的代码也适用于之前未计划的情况。

当然,当您实现新属性并期望代码的行为不同时,省略更新此开关将是一个容易发现的错误。

答案 3 :(得分:1)

  

我再做一次不必要的初始化

我也不喜欢那样。

就像许多人已经说过的那样,在default:语句中添加额外的switch部分。像这样:

Control myControl;
switch(x)
{
  case TabType.Edit:
    myControl= ...;
    break;

  case TabType.View:
    myControl= ...;
    break;

  default:
    throw new Exception("Unexpected value of x: " + x);        
 }

 myPageView.Controls.Add(myControl);

这是因为根据您的问题,我们了解您知道 x将始终拥有这两个值中的一个。编译器不知道这一点。上面的代码会告诉你。

答案 4 :(得分:0)

你必须做两个选择之一;或者在switch之前指定初始值,或者添加default大小写,以便编译器确定switch将初始化变量。

我建议如果开关没有初始化变量,你可能只想抛出异常。在这种情况下,只需将该代码添加到default案例中即可。这样一来,当测试开发人员忘记为新的枚举值添加case时,就会明白这一点,而不是只是默默无法工作。