2010-09-28 5 views
3

Я пишу некоторые функциональные возможности Enum, и следующее:Преобразование Null в Nullable Enum (Generic)

public static T ConvertStringToEnumValue<T>(string valueToConvert, 
    bool isCaseSensitive) 
{ 
    if (String.IsNullOrWhiteSpace(valueToConvert)) 
     return (T)typeof(T).TypeInitializer.Invoke(null); 

    valueToConvert = valueToConvert.Replace(" ", ""); 
    if (typeof(T).BaseType.FullName != "System.Enum" && 
     typeof(T).BaseType.FullName != "System.ValueType") 
    { 
     throw new ArgumentException("Type must be of Enum and not " + 
      typeof (T).BaseType.FullName); 
    } 

    if (typeof(T).BaseType.FullName == "System.ValueType") 
    { 
     return (T)Enum.Parse(Nullable.GetUnderlyingType(typeof(T)), 
      valueToConvert, !isCaseSensitive); 
    } 

    return (T)Enum.Parse(typeof(T), valueToConvert, !isCaseSensitive); 
} 

Теперь я называю это следующим:

EnumHelper.ConvertStringToEnumValue<Enums.Animals?>("Cat"); 

Это работает, как ожидалось , Однако, если я запустил это:

EnumHelper.ConvertStringToEnumValue<Enums.Animals?>(null); 

он ломается с ошибкой, что TypeInitializer имеет значение NULL.

Кто-нибудь знает, как это решить?

Спасибо всем!

+1

Почему на земле вы вызова типа инициализатору ?? В мои 9 лет C#, я ** никогда не должен был этого делать! – leppie

+0

На самом деле этот инициализатор не возвращает ничего. Код поддельный, извините. – leppie

+1

@leppie, отсюда мой вопрос. Я ищу способ сделать это, и, очевидно, TypeInitializer не является правильным способом сделать это. Нижеприведенный ответ от Preet - это то, что я искал. – Richard

ответ

9

попробовать

if (String.IsNullOrWhiteSpace(valueToConvert)) 
       return default(T); 
0

У меня есть другой подход, используя расширение и дженерики.

public static T ToEnum<T>(this string s) { 
    if (string.IsNullOrWhiteSpace(s)) 
     return default(T); 

    s = s.Replace(" ", ""); 
    if (typeof(T).BaseType.FullName != "System.Enum" && 
     typeof(T).BaseType.FullName != "System.ValueType") { 
     throw new ArgumentException("Type must be of Enum and not " + typeof(T).BaseType.FullName); 
    } 

    if (typeof(T).BaseType.FullName == "System.ValueType") 
     return (T)Enum.Parse(Nullable.GetUnderlyingType(typeof(T)), s, true); 

    return (T)Enum.Parse(typeof(T), s, true); 
} 

использования, как это ...

Gender? g = "Female".ToEnum<Gender?>(); 
0

Это один получает работу, и это также выглядит довольно. Надеюсь, поможет!

/// <summary> 
    /// <para>More convenient than using T.TryParse(string, out T). 
    /// Works with primitive types, structs, and enums. 
    /// Tries to parse the string to an instance of the type specified. 
    /// If the input cannot be parsed, null will be returned. 
    /// </para> 
    /// <para> 
    /// If the value of the caller is null, null will be returned. 
    /// So if you have "string s = null;" and then you try "s.ToNullable...", 
    /// null will be returned. No null exception will be thrown. 
    /// </para> 
    /// <author>Contributed by Taylor Love (Pangamma)</author> 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="p_self"></param> 
    /// <returns></returns> 
    public static T? ToNullable<T>(this string p_self) where T : struct 
    { 
     if (!string.IsNullOrEmpty(p_self)) 
     { 
      var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)); 
      if (converter.IsValid(p_self)) return (T)converter.ConvertFromString(p_self); 
      if (typeof(T).IsEnum) { T t; if (Enum.TryParse<T>(p_self, out t)) return t;} 
     } 

     return null; 
    } 

https://github.com/Pangamma/PangammaUtilities-CSharp/tree/master/src/StringExtensions