Enum from string, int, etc
Solution 1
I would avoid polluting int or string with extension methods for enums, instead a good old fashioned static helper class might be in order.
public static class EnumHelper
{
public static T FromInt<T>(int value)
{
return (T)value;
}
public static T FromString<T>(string value)
{
return (T) Enum.Parse(typeof(T),value);
}
}
Solution 2
Do you really need those extension methods?
MyEnum fromInt = (MyEnum)someIntValue;
MyEnum fromString = (MyEnum)Enum.Parse(typeof(MyEnum), someStringValue, true);
int intFromEnum = (int)MyEnum.SomeValue;
string stringFromEnum = MyEnum.SomeValue.ToString();
Solution 3
The other way around would be possibly... the other way around ;) Extend int and string with generic extension methods which will take as type parameter the type of an enum:
public static TEnum ToEnum<TEnum>(this int val)
{
return (TEnum) System.Enum.ToObject(typeof(TEnum), val);
}
public static TEnum ToEnum<TEnum>(this string val)
{
return (TEnum) System.Enum.Parse(typeof(TEnum), val);
}
Usage:
var redFromInt = 141.ToEnum<System.Drawing.KnownColor>();
var redFromString = "Red".ToEnum<System.Drawing.KnownColor>();
There is unfortunately no generic constraint for Enums, so we have to check TEnum type during runtime; to simplify we'll leave that verification to Enum.ToObject
and Enum.Parse
methods.
Solution 4
why do you want FromInt an extenstion method versus just casting it?
MyEnum fromInt;
if(Enum.IsDefined(typeof(MyEnum), intvalue))
{
fromInt = (MyEnum) intvalue;
}
else
{
//not valid
}
alternatively, for strings, you can use Enum.TryParse
MyEnum fromString;
if (Enum.TryParse<MyEnum>(stringvalue, out fromString))
{
//succeeded
}
else
{
//not valid
}
Solution 5
Another approach (for the string part of your question):
/// <summary>
/// Static class for generic parsing of string to enum
/// </summary>
/// <typeparam name="T">Type of the enum to be parsed to</typeparam>
public static class Enum<T>
{
/// <summary>
/// Parses the specified value from string to the given Enum type.
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static T Parse(string value)
{
//Null check
if(value == null) throw new ArgumentNullException("value");
//Empty string check
value = value.Trim();
if(value.Length == 0) throw new ArgumentException("Must specify valid information for parsing in the string", "value");
//Not enum check
Type t = typeof(T);
if(!t.IsEnum) throw new ArgumentException("Type provided must be an Enum", "T");
return (T)Enum.Parse(typeof(T), value);
}
}
(Partially inspired by: http://devlicious.com/blogs/christopher_bennage/archive/2007/09/13/my-new-little-friend-enum-lt-t-gt.aspx)
Related videos on Youtube
Comments
-
Louis Rhys almost 2 years
Using extension method we can create methods to convert an enum to other datatype like string, int by creating extension methods
ToInt()
,ToString()
, etc for the enum.I wonder how to implement the other way around, e.g.
FromInt(int)
,FromString(string)
, etc. As far as I know I can't createMyEnum.FromInt()
(static) extension method. So what are the possible approaches for this?-
Oded over 13 yearsYou make the extension method on
int
andstring
, not theenum
... -
Louis Rhys over 13 yearswouldn't that kind of pollute
int
andstring
since they are used a lot and mostly not related to my enum?
-
-
Louis Rhys over 13 yearsre your question: I am creating a wrapper around more than one library. They don't have the same convention regarding some string, so I try to create an enum so that they'll have the same convention.
-
Louis Rhys over 13 yearsWhat if stringvalue and intvalue is not the same as the underlying value?
-
Veeru over 13 yearsI don't quite get what you are saying. Are you asking what happens in the string or int do not represent any of the enum values?
-
Cel over 12 years
FromInt
does not compile for me, Cannot convert type 'int' to 'T' ? -
Cel over 12 yearsI'm not even calling it and compilation fails - I got this to work instead:
public static T ToEnum<T>(this int value) { return (T)Enum.Parse(typeof(T), value.ToString()); }
-
Louise Eggleton about 8 yearsI like that this is one method with different overloads.