string aStr = "Truncate";
FileInfo aFN = (FileInfo) Enum.Parse(
typeof(FileInfo), aStr);
First, we have to provide the type of the enumeration twice. Second, I personally hate nested parentheses. I just cannot read the code with too many parentheses.
What I suggest is a thin wrapper:
public static class EnumParser<tEnum>
where tEnum : struct
{
public static tEnum Parse(string theVal)
{
return (tEnum)Enum.Parse(
typeof(tEnum), theVal);
}
public static tEnum Parse(string theVal, tEnum theDef)
{
try { return Parse(theVal); }
catch (ArgumentException) { return theDef; }
}
}
After several years of programming in C# I found I constantly use the exact same approach in most or all of my projects so I added it to my small C# toolkit.
The initial example would look more elegant with this new class in scope:
string aStr = "Truncate";
FileInfo aFN = EnumParser<FileInfo>.Parse(aStr);
The second overload allows us to use a default value:
string aStr = "Unknown";
FileInfo aFN = EnumParser<FileInfo>.Parse(
aStr, FileInfo.Truncate);
The provided solution is good but not perfect. Let's create another version of the EnumParser class:
public static class EnumParser
{
public static tEnum Parse<tEnum>(
string theVal) where tEnum : struct
{
return (tEnum)Enum.Parse(
typeof(tEnum), theVal);
}
public static tEnum Parse<tEnum>(
string theVal, tEnum theDef) where tEnum : struct
{
try { return Parse<tEnum>(theVal); }
catch (ArgumentException) { return theDef; }
}
}
As you see, we moved from a generic type to a non-generic type with two generic methods. Now let's look at the usage:
string aStr = "Truncate";
FileInfo aFN = EnumParser.Parse<FileInfo>(aStr);
The usage example when we don't specify a default value is almost identical to that of the generic type. However, things change significantly when a default value comes into play:
string aStr = "Unknown";
FileInfo aFN = EnumParser.Parse(aStr, FileInfo.Truncate);
As you see, we don't even specify the generic method arguments and the code will still compile successfully. The reason is: the compiler can resolve the arguments of the generic method from the argument that we specified. Our default value argument has now two roles: first, it is the value that will be returned in case the string is not recognized; second, it is an implicit type specifier for a generic method.
This is, of course, my favorite way to parse enums.
Cheers,
Kirill
Nice pattern. Will definitely use it next time.
ReplyDeleteI was not able to understand what this article was talking about, but this sounds interesting. I'm also learning C# & had just stepped-in. Plz forgive my lack of understanding, I just had a doubt....
ReplyDeleteI have Windows form form1 & added form2. I wanted to use form2 as a message window which will disappear after some interval of time. (just like a popup)
Now how to do that? Can u use some simple way to make me understand that? sample code is always a wonderful help. :)
Buy a book.
ReplyDelete