Enum из строки, int и т. Д. - PullRequest
       44

Enum из строки, int и т. Д.

26 голосов
/ 18 января 2011

Используя метод расширения, мы можем создать методы для преобразования перечисления в другой тип данных, такой как string, int, создав для него методы расширения ToInt(), ToString() и т. Д.наоборот, например FromInt(int), FromString(string) и т. д. Насколько я знаю, я не могу создать MyEnum.FromInt() (статический) метод расширения.Итак, каковы возможные подходы к этому?

Ответы [ 7 ]

33 голосов
/ 18 января 2011

Я бы не стал загрязнять int или string методами расширения для перечислений, вместо этого мог бы подойти старый классический статический вспомогательный класс.

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);
  }
}
21 голосов
/ 18 января 2011

Вам действительно нужны эти методы расширения?

MyEnum fromInt = (MyEnum)someIntValue;
MyEnum fromString = (MyEnum)Enum.Parse(typeof(MyEnum), someStringValue, true);

int intFromEnum = (int)MyEnum.SomeValue;
string stringFromEnum = MyEnum.SomeValue.ToString();
7 голосов
/ 18 января 2011

И наоборот, возможно ... наоборот;) Расширить int и строку с помощью универсальных методов расширения , которые будут принимать в качестве параметра типа тип перечисления:

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);
}

Использование:

var redFromInt = 141.ToEnum<System.Drawing.KnownColor>();
var redFromString = "Red".ToEnum<System.Drawing.KnownColor>();

К сожалению, для Enums нет общего ограничения, поэтому мы должны проверять тип TEnum во время выполнения; для упрощения мы оставим эту проверку для методов Enum.ToObject и Enum.Parse.

4 голосов
/ 18 января 2011

зачем вам FromInt метод расширения вместо простого его приведения?

MyEnum fromInt;
if(Enum.IsDefined(typeof(MyEnum), intvalue))
{
    fromInt = (MyEnum) intvalue;
}
else
{
    //not valid
}

в качестве альтернативы, для строк вы можете использовать Enum.TryParse

MyEnum fromString;
if (Enum.TryParse<MyEnum>(stringvalue, out fromString))
{
    //succeeded
}
else
{
    //not valid
}
3 голосов
/ 18 января 2011

Другой подход (для строковой части вашего вопроса):

/// <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);
    }
}

(Частично вдохновлено: http://devlicious.com/blogs/christopher_bennage/archive/2007/09/13/my-new-little-friend-enum-lt-t-gt.aspx)

2 голосов
/ 18 января 2011

Вы можете сделать:

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);
    }
}

Или:

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);
    }
}
0 голосов
/ 18 января 2011

Вы можете создавать методы расширения для int и string.

Или создайте статический метод для другого статического класса. Может быть, что-то вроде EnumHelper.FromInt (int).

Но я бы поставил один вопрос: почему вы хотите конвертировать в string или int? Это не то, как вы обычно работаете с перечислимыми, кроме, может быть, сериализации. Но это должно обрабатываться какой-то инфраструктурой, а не вашим собственным кодом.

...