我所拥有的是简单的开关语句
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枚举类型)。
在这种情况下,最佳方法是什么?
答案 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
时,就会明白这一点,而不是只是默默无法工作。