2012-03-19 15 views
8

Estoy tratando de analizar una cadena de nuevo a una propiedad anulable de tipo MyEnum.Parse to Nullable Enum

public MyEnum? MyEnumProperty { get; set; } 

Recibo un error en la línea:

Enum result = Enum.Parse(t, "One") as Enum; 
// Type provided must be an Enum. Parameter name: enumType 

tengo una prueba de consola de ejemplo a continuación. El código funciona si elimino el valor de NULL en la propiedad MyEntity.MyEnumProperty.

¿Cómo puedo hacer que el código funcione sin conocer el tipo de enum excepto por reflexión?

static void Main(string[] args) 
    { 
     MyEntity e = new MyEntity(); 
     Type type = e.GetType(); 
     PropertyInfo myEnumPropertyInfo = type.GetProperty("MyEnumProperty"); 

     Type t = myEnumPropertyInfo.PropertyType; 
     Enum result = Enum.Parse(t, "One") as Enum; 

     Console.WriteLine("result != null : {0}", result != null); 
     Console.ReadKey(); 
    } 

    public class MyEntity 
    { 
     public MyEnum? MyEnumProperty { get; set; } 
    } 

    public enum MyEnum 
    { 
     One, 
     Two 
    } 
} 

Respuesta

14

Adición de un caso especial para Nullable<T> funcionará:

Type t = myEnumPropertyInfo.PropertyType; 
if (t.GetGenericTypeDefinition() == typeof(Nullable<>)) 
{ 
    t = t.GetGenericArguments().First(); 
} 
+1

de oro! Muchas gracias –

+0

Sé que esto es de 2012, pero para cualquiera que tropezó con el mismo problema (como yo) - Una pequeña mejora: Agregar un cheque para t.IsGenericType antes de t.GetGenericTypeDefinition() == ..., de lo contrario el código podría romperse para un tipo de enumeración no nulo –

0

Aquí tienes. Una extensión de cadena que te ayudará con esto.

/// <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