Long overdue Enum goodness in .NET 4

Posted by Reed on Monday, October 26, 2009 · 12 Comments

The more I investigate the changes in Version 4 of the .NET framework, the more I find little tweaks that just reduce the pain of day to day programming. For example, the System.Enum class is getting some extra methods that finally make day to day programming a bit simpler.

The first important addition to System.Enum is the addition of Enum.TryParse<T>. This has some great advantages over the .NET 3.5 and earlier parsing of enum values, including the ability to have error checking without throwing exceptions and to have type safety which avoids boxing and casting.

This just is nice – even the MSDN samples just look more clean and elegant. Consider the original Enum.Parse sample:

try { Colors colorValue = (Colors) Enum.Parse( typeof (Colors), colorString, true ); } catch (ArgumentException e) { // Handle errors }

In order for this to work correctly, we need to wrap the entire thing in a try/catch block to handle the potential exception, we have to cast our results from System.Object back to “Colors”, and we have to specify the type explicitly (typeof(Colors)) in the call. Not very friendly.

In .NET 4, we can simplify this dramatically:

Colors colorValue; if (!Enum.TryParse(colorString, true , out colorValue)) { // Handle error }

Not only is this safer (you’re now getting compile-time checking that it’s the correct type of Enum), you don’t have to use exception handling for a simple case like this. In addition, you’re avoiding boxing the result into an object and casting it back (unboxing it) to a Colors type. Very nice addition!

The second addition to Enum is just as exciting – Enum.HasFlag. Dealing with flag enum values has always been problematic, and a source of confusion for many people. In .NET 3.5, if you want to check for the existence of a flag, it was odd to say the least. For example, say we have the following flags enum:

[Flags] enum TestFlags { One = 1, Two = 2, Four = 4, Eight = 8, Sixteen = 16 }

In .NET 3.5, to check for the existence of a flag, you had to write:

bool hasOneFlag = (variable & TestFlags.One) == TestFlags.One;

Definitely not short to type, and quite confusing for many beginning programmers. Many people (including myself) have tried to create extension methods to ease this, the best probably being Jon Skeet’s Unconstrained Melody, which adds a HasAny() extension method for enum. However, this approach required IL rewriting, and was impossible to accomplish in C# directly.

Version 4 of the .NET Framework finally addresses this very common scenario with the addition of Enum.HasFlag. This lets us simplify the above line to:

bool hasOneFlag = variable.HasFlag(TestFlags.One);

This is much easier to understand, less confusing to type, and very nice overall.

Here’s a short program demonstrating both of these new methods:

[Flags] enum TestFlags { One = 1, Two = 2, Four = 4, Eight = 8, Sixteen = 16 } class Program { static void Main( string [] args) { TestFlags variable; Enum.TryParse( "Eight, sixteen" , true , out variable); Console.WriteLine(variable); Console.WriteLine(variable.HasFlag(TestFlags.Two)); Console.WriteLine(variable.HasFlag(TestFlags.Eight)); Console.WriteLine(variable.HasFlag(TestFlags.Sixteen)); Console.ReadKey(); } }

When run, this outputs:

Eight, Sixteen False True True

Very nice additions!