2012-12-20 73 views
6

我有什么是简单的开关语句变量的初始化问题

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

    case TabType.View: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

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

局部变量myControl可能无法访问

之前被初始化

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

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

CASE 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)。

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

+0

编译器给你答案只是将它设置为null本地你的错误“变量myControl可能在访问前未初始化” – MethodMan

回答

5

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

如果您担心可能引入新的枚举值,那么您可以在default子句中引发一个有意义的异常。这样可以防止您在稍后尝试解除引用该变量时出现更模糊的NullReferenceException

+2

当'default'情况下是抛出异常时+1击中。也是一个很好的选择。 –

+1

感谢大家:)抛出有意义的异常的默认子句是不错的方法。 –

+0

Chuck Norris可以安全地引用Null引用而不会收到NullReferenceException – user93353

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: 
    // .. 
} 
验证一个实例进行得(而不是依赖于它被分配)之前创建的
+1

你的第二个例子是他的第二个例子。 – Servy

+1

@ServyL是的,但我已经明确声明,而不是免除'default(Tabtype)'的值,只是使用'default:'。 –

+0

@DJKRAZE错字,修正。 – Servy

2

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

增加了一些新的特性,以我的枚举它将为所有其他类型做默认

它可以让你的代码在默认的前提下工作(抛出一个异常或设置为一个众所周知的值),因此您的代码也适用于以前没有计划的情况。

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

0

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

我会建议,如果交换机不初始化变量可能你只是想抛出一个异常。在这种情况下,只需将该代码添加到default的情况。通过这种方式,在开发人员忘记为新的枚举值添加case而不是仅仅默默无闻地工作时,测试就很清楚。

1

我做一件不必要的initalization

我也不喜欢这样。

就像很多人已经说过的,为您的switch声明添加额外的default:部分。就像这样:

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总会有这两个值中的一个。编译器不知道这一点。上面的代码会告诉它。