问题
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 create MyEnum.FromInt()
(static) extension method. So what are the possible approaches for this?
回答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);
}
}
回答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();
回答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.
回答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
}
回答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)
回答6:
You can do:
public static class EnumExtensions
{
public static Enum FromInt32(this Enum obj, Int32 value)
{
return (Enum)((Object)(value));
}
public static Enum FromString(this Enum obj, String value)
{
return (Enum)Enum.Parse(obj.GetType(), value);
}
}
Or:
public static class Int32Extensions
{
public static Enum ToEnum(this Int32 obj)
{
return (Enum)((Object)(obj));
}
}
public static class StringExtensions
{
public static Enum ToEnum(this Enum obj, String value)
{
return (Enum)Enum.Parse(obj.GetType(), value);
}
}
回答7:
You can either make extension methods on int and string.
Or make static method on some other static class. Maybe something like EnumHelper.FromInt(int).
But I would pose one question : Why do you want to convert to string or int? Its not how you normaly work with enumerables, except maybe serialisation. But that should be handled by some kind of infrastructure, not your own code.
来源:https://stackoverflow.com/questions/4722010/enum-from-string-int-etc