Compiler complains about unrecognized variable after enabling enum

I have the following counter:

enum Foo { Bar, Baz };

      

In the following code, the compiler aborts with an error:

use of unassigned local variable 'str'

Code:

string str;
Foo foo = Foo.Bar;

switch (foo)
{
    case Foo.Bar: str = "a"; break;
    case Foo.Baz: str = "b"; break;
}

str.ToLower();

      

switch

covers all possible values ​​of the enumerator. But the compiler still thinks it str

might not be assigned. Why is this? Of course, I could put a case in there default

, but that would be wrong since the errors were not caught at compile time. For example, if the Foo

enum is later changed and a new value added, it would be nice to get a compiler error. If I use case default

then no error will be detected when recompiled.

I suppose there is no way to force the compiler to accept switch

without case default

and throw an error if Foo

expanded later?

+3


source to share


5 answers


I suppose there is no way to force the compiler to accept a switch without the default case and throw an error if Foo is expanded later?

It is right. In short, the reason the compiler does this is because it is possible to assign a foo

value that is not a valid value enum Foo

by creating a type int

, thus avoiding all cases switch

.



The solution I use in situations like this is to add a statement:

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);
}

      

+2


source


The enumerations are statically typed and type checked. But validation is not extended to ensure that enumeration values ​​only allow specific values. In fact, for variables, Flags

enumerations often do not take on any particular value.

Like:

Foo f = (Foo)1234; //valid

      



And so it switch

can choose a case default

at runtime, or it str

can be used in an uninitialized state.

Some languages ​​have stronger constructs than .NET enums, such as Haskell and F #.

+1


source


An enumeration is essentially an int, and any int value can be assigned to it. This usually doesn't happen, but that's why you need to handle the default case or just declare the string with a default value (e.g. null)

+1


source


Of course, I could put the default case in there, but that would be wrong

It would be good practice. Your enum may still contain other numeric values ​​because enums in C # only constitute a compile-time layer above the underlying numeric representation - think const

. Foo f = (Foo)int.MaxValue;

will still compile and run, but now you don't have a switch case for it.

Depending on your interface, you can either put a default case with an exception, define str

with zero, or an empty string.

+1


source


your best bet is to just initialize str with an empty string on your first line. the compiler cannot (or will not) try to deeply analyze the switch logic.

0


source







All Articles