I am converting a numeric value that is of string type into a corresponding Enum. While I was testing my code, I discovered interesting behavior that has me confused.
Using the code example below, can somebody shed light on why an exception isn't thrown if/when the "s" variable has a value that doesn't match one of the Enum values? Also, how is that the sEnum var can be set to a value that doesn't exist within the definition of the Stooge enum?
class Program
{
enum Stooge
{
Unspecified,
Moe,
Larry,
Curly,
Shemp
}
static void Main(string[] args)
{
while (true)
{
Console.WriteLine("Enter a number...");
string s = Console.ReadLine();
Stooge sEnum = (Stooge)(int.Parse(s)); //Why doesn't this line throw if s != 0, 1, 2, 3, or 4?
Console.WriteLine("\r\nYou entered: {0}\r\nEnum String Value: {1}\r\nEnum Int Value: {2}\r\n", s, sEnum.ToString(), (int)sEnum);
}
}
}
I changed the implementation from https://stackoverflow.com/a/4892571/275388 to remedy two issues
DefinedCast(object enumValue)
signature indicates that the code can be used withstring
andint
types (and also needlessly boxes the later).Enum.IsDefined
/Enum.Parse
both allocate an array throughEnum.GetValues(typeof(TEnum))
which actually caused needles slowdown for my use-case - this can be avoided at the expense of caching a map.Hence I wound up with
Use int.Parse() if you wan't an exception to be thrown in the case the value passed is not parsable. Use int.TryParse() if you wan't to parse a value that might be invalid without an exception to be thrown.
This was a decision on the part of the people who created .NET. An enum is backed by another value type (
int
,short
,byte
, etc), and so it can actually have any value that is valid for those value types.I personally am not a fan of the way this works, so I made a series of utility methods:
This way, I can say:
... or:
Enum is really thin wrapper over
int
. Basically it isint
+ static collection of possible values (sort of constants). All the checks are at compile time, type checking etc. But when you actually castint
toenum
runtime doesn't care. So validate your input!An enum is just technically an int (or whatever you have defined the enum's underlying type to be). you can check for a corresponding value in the enum, though with a call to
Enum.IsDefined
. More info here: Cast int to enum in C#