Warning : This page has been marked as an archive because the author consider that its content is no longer relevant.

Recently I encountered a cast that I found interesting. It was trying to convert an integer into an enumeration in a way I never met before. Let’s take this enumeration type :

public enum MyEnum
{
    Zero = 0,
    One = 1
}

And the following cast :

MyEnum res;
int val = 1;

res = (MyEnum)Enum.Parse(typeof(MyEnum), val.ToString());

My first reaction was to wonder why converting an integer into a string to cast it into an enumeration just after when a simple direct cast is enough ?

res = (MyEnum)val;

I ask a workmate If I didn’t miss a thing and I was answered that Enum.Parse throws an exception if the val variable has a value that doesn’t fit in the enumeration (for example 2).

As I was not totally convinced I decided to create a little test :

// Cast 1
res = (MyEnum)Enum.ToObject(typeof(MyEnum), val);
Console.Out.WriteLine("{0}", res);

// Cast 2
res = (MyEnum)Enum.Parse(typeof(MyEnum), val.ToString(CultureInfo.InvariantCulture));
Console.Out.WriteLine("{0}", res);

// Cast 3
res = (MyEnum)val;
Console.Out.WriteLine("{0}", res);

With all of these tests I realized all the casts were working with a value of 2. No exception thrown. This means that the numerical value of res is 2 when the maximum value of the enumeration is 1 ! This feels like C.

Now what happens with the following test:

// Cast 4
string sVal = "Two";
res = (MyEnum)Enum.Parse(typeof(MyEnum), sVal);
Console.Out.WriteLine("{0}", res);

This time we have got an exception indicating that the value “Two” doesn’t exist in the enumeration, which is an expected behavior.

If we go back to the code that troubled me at the beginning of this post we realize the developer error was to think that Enum.Parse works the same way with strings than with strings containing an integer.

Therefore how can we be sure that the value we want to convert exists in the enumeration ?

We have many choices :

if (typeof(MyEnum).IsEnumDefined(val))
{
    res = (MyEnum)val;
    Console.Out.WriteLine("{0}", res);
}
else
    Console.Out.WriteLine("Cannot convert {0} to MyEnum", val);

if (Enum.IsDefined(typeof(MyEnum), val))
{
    res = (MyEnum) val;
    Console.Out.WriteLine("{0}", res);
}
else
    Console.Out.WriteLine("Cannot convert {0} to MyEnum", val);

The first method only exists starting .NET 4 whereas the second exists in the previous framework versions too.

We learn everyday our favorite language :-)

Did you expect such a behavior ?

Comments