6

我所拥有的是简单的 switch 语句

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 无论如何都会被初始化并且不会抛出异常。

案例二:

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

     default:
     {

         myControl= ...;
     }
 }

 myPageView.Controls.Add(myControl);

但是这种情况看起来不太好,因为在我的枚举中添加了一些新属性后,它将默认为所有其他类型(开发人员很容易忘记在这里更改代码,或者不需要为其他枚举类型初始化 myControl) .

在这种情况下最好的方法是什么?

4

5 回答 5

6

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

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

于 2012-12-20T15:40:03.487 回答
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:
    // ..
}
于 2012-12-20T15:38:20.093 回答
2

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

向我的枚举添加一些新属性,它将默认为所有其他类型

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

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

于 2012-12-20T15:39:42.187 回答
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将始终具有这两个值之一。编译器不知道这一点。上面的代码会告诉它。

于 2012-12-20T15:48:09.387 回答
0

您必须执行以下两个选项之一;要么在 之前指定初始值switch,要么添加一个default案例,以便编译器确定switch将初始化变量。

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

于 2012-12-20T15:39:55.410 回答