C# 编译器在打开枚举后抱怨未分配变量
我有下列统计员:C# 编译器在打开枚举后抱怨未分配变量,c#,enums,switch-statement,C#,Enums,Switch Statement,我有下列统计员: enum Foo { Bar, Baz }; 在以下代码中,编译器将中止并显示错误: use of unassigned local variable 'str' 开关覆盖枚举数的所有可能值。但是编译器仍然认为str可能是未赋值的。为什么呢?当然,我可以在那里放一个default大小写,但那是错误的,因为在编译时不会捕获错误。例如,如果以后修改了Fooenum并添加了一个新值,那么最好得到一个编译器错误。如果我使用默认值案例,则在重新编译时不会捕获错误 我想如果以后扩展了Fo
enum Foo { Bar, Baz };
在以下代码中,编译器将中止并显示错误:
use of unassigned local variable 'str'
开关
覆盖枚举数的所有可能值。但是编译器仍然认为str
可能是未赋值的。为什么呢?当然,我可以在那里放一个default
大小写,但那是错误的,因为在编译时不会捕获错误。例如,如果以后修改了Foo
enum并添加了一个新值,那么最好得到一个编译器错误。如果我使用默认值
案例,则在重新编译时不会捕获错误
我想如果以后扩展了
Foo
,编译器就无法在没有默认值的情况下接受开关
,并引发错误?枚举是静态类型并进行类型检查的。但检查并没有扩展到确保枚举值仅采用定义的值。事实上,对于标志
枚举变量通常不采用任何单个定义值
就像这样:
Foo f = (Foo)1234; //valid
这就是为什么开关
可以在运行时选择默认
情况,并且str
可能最终在未初始化状态下使用
有些语言的结构比.NET枚举(如Haskell和F#)更强。最好的办法是在第一行中用空字符串初始化str。编译器不能(或不会)深入分析开关逻辑
我想如果以后扩展了Foo,那么没有办法让编译器接受没有默认大小写的开关并引发错误
这是正确的。长话短说,编译器之所以这样做,是因为可以通过键入int
来分配foo
一个不是有效enum foo
s值之一的值,从而可以绕过开关的所有情况
我在这种情况下使用的解决方案是添加断言:
switch (foo)
{
case Foo.Bar: str = "a"; break;
case Foo.Baz: str = "b"; break;
default: Debug.Assert(false, "An enum value is not covered by switch: "+foo);
}
枚举本质上是一个int,任何int值都可以分配给它。这通常不会发生,但这就是为什么您需要处理默认情况,或者只需使用默认值(如null)声明字符串
当然,我可以在那里放一个默认案例,但那是错误的
这将符合良好做法。您的枚举仍然可以包含其他数值,因为C#中的枚举只是底层数值表示之上的编译时层—想想const
字段<代码>Foo f=(Foo)int.MaxValue
仍将编译并运行,但现在您没有它的切换用例
根据您的界面,您可以将带有异常的默认大小写放在那里,用null定义str
,或空字符串。在这种情况下,断言看起来是最好的主意。您可以使用Debug.Fail(…)
而不是Debug.Assert(false)
。最后一个开关部分是如何进行的?您会给str
和break
分配一个伪值(如null
)吗?或者你会抛出
?你不能“失败”;交换机段的端点必须不可访问。
switch (foo)
{
case Foo.Bar: str = "a"; break;
case Foo.Baz: str = "b"; break;
default: Debug.Assert(false, "An enum value is not covered by switch: "+foo);
}