Есть ли лучший способ создать общую строку преобразования в метод enum или расширение enum? - PullRequest
5 голосов
/ 17 апреля 2010

У меня есть следующие методы в классе enum helper (я упростил его для целей вопроса):

static class EnumHelper
{
    public enum EnumType1 : int
    {
        Unknown = 0,
        Yes = 1,
        No = 2
    }

    public enum EnumType2 : int
    {
        Unknown = 0,
        Dog = 1,
        Cat = 2,
        Bird = 3
    }

    public enum EnumType3
    {
        Unknown,
        iPhone,
        Andriod,
        WindowsPhone7,
        Palm
    }

    public static EnumType1 ConvertToEnumType1(string value)
    {
        return (string.IsNullOrEmpty(value)) ?
            EnumType1.Unknown :
            (EnumType1)(Enum.Parse(typeof(EnumType1), value, true));
    }

    public static EnumType2 ConvertToEnumType2(string value)
    {
        return (string.IsNullOrEmpty(value)) ?
            EnumType2.Unknown :
            (EnumType2)(Enum.Parse(typeof(EnumType2), value, true));
    }

    public static EnumType3 ConvertToEnumType3(string value)
    {
        return (string.IsNullOrEmpty(value)) ?
            EnumType3.Unknown :
            (EnumType3)(Enum.Parse(typeof(EnumType3), value, true));
    }
}

Таким образом, вопрос здесь заключается в том, можно ли обрезать это до метода расширения Enum или, возможно, какого-то одного типа метода, который может обрабатывать любой тип. Я нашел несколько примеров, чтобы сделать это с базовыми перечислениями, но разница в моем примере состоит в том, что все перечисления имеют элемент Unknown, который мне нужно вернуть, если строка пуста или пуста (если совпадение не найдено, я хочу, чтобы оно не получилось) .

Может быть поискать что-то вроде следующего:

EnumType1 value = EnumType1.Convert("Yes");
// or
EnumType1 value = EnumHelper.Convert(EnumType1, "Yes");

Одна функция, которая делает все это ... как обращаться с элементом Unknown - это часть, на которой я зависаю.

Редактировать: Исправлено одно из перечислений, чтобы не быть определенными с целыми числами. Таким образом, я могу гарантировать, что 0 всегда будет иметь место, но Unknown всегда будет правильным текстом ... Я думаю, я мог бы использовать тот же пример, что и T (0), но выполнить другой анализ текста "Неизвестно".

Ответы [ 2 ]

8 голосов
/ 17 апреля 2010

Используйте это, предполагая, что Unknown всегда равен 0.

public static T ConvertToEnum<T>(this string value) where T : new()
{
    if( !typeof(T).IsEnum )
        throw new NotSupportedException( "T must be an Enum" );

    try
    {
        return (T)Enum.Parse(typeof(T), value);
    }
    catch
    {
        return default(T); // equivalent to (T)0
        //return (T)Enum.Parse(typeof(T), "Unknown"));
    }
}

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

EnumType2 a = "Cat".ConvertToEnum<EnumType2>(); 
EnumType2 b = "Person".ConvertToEnum<EnumType2>(); // Unknown

РЕДАКТИРОВАТЬ По OP (Келси): Ваш ответ привел меня к правильному ответу, поэтому я решил добавить его сюда:

public static T ConvertTo<T>(this string value)
{
    T returnValue = (T)(Enum.Parse(typeof(T), "Unknown", true));
    if ((string.IsNullOrEmpty(value) == false) && 
        (typeof(T).IsEnum))
    {
        try { returnValue = (T)(Enum.Parse(typeof(T), value, true)); }
        catch { }
    }
    return returnValue;
}
2 голосов
/ 17 апреля 2010

использовать дженерики ... как-то так ...

public static TResult ConvertTo<TResult>( this string source )
{
     if( !typeof(TResult).IsEnum )
     {
         throw new NotSupportedException( "TResult must be an Enum" );
     }

    if (!Enum.GetNames(typeof(TResult)).Contains(source))
        return default(TResult);


     return (TResult)Enum.Parse( typeof(TResult), source );
}

( код пришёл отсюда )

...