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?
source to share
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);
}
source to share
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 #.
source to share
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.
source to share