2009-10-08 12 views
9

Tengo el siguiente código:¿Cómo saber si un PropertyInfo es de un tipo de enumeración particular?

public class DataReader<T> where T : class 
{ 
    public T getEntityFromReader(IDataReader reader, IDictionary<string, string> FieldMappings) 
    { 
     T entity = Activator.CreateInstance<T>(); 
     Type entityType = entity.GetType(); 
     PropertyInfo[] pi = entityType.GetProperties(); 
     string FieldName; 

     while (reader.Read()) 
     { 
      for (int t = 0; t < reader.FieldCount; t++) 
      { 
       foreach (PropertyInfo property in pi) 
       { 
        FieldMappings.TryGetValue(property.Name, out FieldName); 

        Type genericType = property.PropertyType; 

        if (!String.IsNullOrEmpty(FieldName)) 
         property.SetValue(entity, reader[FieldName], null); 
       } 
      } 
     } 

     return entity; 
    } 
} 

Cuando llego a un campo de tipo Enum, o en este caso NameSpace.MyEnum, quiero hacer algo especial. No puedo simplemente SetValue porque el valor que proviene de la base de datos es digamos "m" y el valor en el Enum es "Mr". Entonces necesito llamar a otro método. ¡Lo sé! Sistemas heredados ¿verdad?

Entonces, ¿cómo puedo determinar cuándo un artículo PropertyInfo es de un tipo de enumeración particular?

Así que en el código anterior me gustaría comprobar primero si el tipo PropertyInfo es de una especificación y si es entonces llamar a mi método y si no, simplemente permita SetValue ejecutar.

+1

En lugar de utilizar Activator.CreateInstance (), simplemente agregue la restricción "nueva" a su genérico: "donde T: clase, nuevo()". Entonces solo usa "T entidad = nueva T()". De esta forma, puede exigir la necesidad de un constructor sin parámetros en tiempo de compilación. – Brannon

+0

@Brannon, gracias, eso es un gran consejo. lo haré cuando entre al trabajo Gracias. – griegs

Respuesta

2
static void DoWork() 
{ 
    var myclass = typeof(MyClass); 
    var pi = myclass.GetProperty("Enum"); 
    var type = pi.PropertyType; 

    /* as itowlson points out you could just do ... 
     var isMyEnum = type == typeof(MyEnum) 
     ... becasue Enums can not be inherited 
    */ 
    var isMyEnum = type.IsAssignableFrom(typeof(MyEnum)); // true 
} 
public enum MyEnum { A, B, C, D } 
public class MyClass 
{ 
    public MyEnum Enum { get; set; } 
} 
+2

Podría ser más claro solo para probar type == typeof (MyEnum). IsAssignableTo no agrega ningún valor porque no puede tener otro tipo derivado de MyEnum. – itowlson

+0

Gracias @Matthew. Funciona como uno comprado. – griegs

3

En el código anterior,

bool isEnum = typeof(Enum).IsAssignableFrom(typeof(genericType)); 

le conseguirá si el tipo de corriente es (derivado de) una enumeración o no.

+0

+1 Gracias @adrianbanks por su contribución. – griegs

20

Esto es lo que utilizo con éxito

property.PropertyType.IsEnum 
0

Esto es cómo manejar al convertir una tabla de datos en una lista inflexible

/// <summary> 
     /// Covert a data table to an entity wiht properties name same as the repective column name 
     /// </summary> 
     /// <typeparam name="T"></typeparam> 
     /// <param name="dt"></param> 
     /// <returns></returns> 
     public static List<T> ConvertDataTable<T>(this DataTable dt) 
     { 
      List<T> models = new List<T>(); 
      foreach (DataRow dr in dt.Rows) 
      { 
       T model = (T)Activator.CreateInstance(typeof(T)); 
       PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T)); 

       foreach (PropertyDescriptor prop in properties) 
       { 
        //get the property information based on the type 
        System.Reflection.PropertyInfo propertyInfo = model.GetType().GetProperties().Last(p => p.Name == prop.Name); 

        var ca = propertyInfo.GetCustomAttribute<PropertyDbParameterAttribute>(inherit: false); 
        string PropertyName = string.Empty; 
        if (ca != null && !String.IsNullOrWhiteSpace(ca.name) && dt.Columns.Contains(ca.name)) //Here giving more priority to explicit value 
         PropertyName = ca.name; 
        else if (dt.Columns.Contains(prop.Name)) 
         PropertyName = prop.Name; 

        if (!String.IsNullOrWhiteSpace(PropertyName)) 
        { 
         //Convert.ChangeType does not handle conversion to nullable types 
         //if the property type is nullable, we need to get the underlying type of the property 
         var targetType = IsNullableType(propertyInfo.PropertyType) ? Nullable.GetUnderlyingType(propertyInfo.PropertyType) : propertyInfo.PropertyType; 
         // var propertyVal = Convert.ChangeType(dr[prop.Name], targetType); 
         //Set the value of the property 
         try 
         { 
          if (propertyInfo.PropertyType.IsEnum) 
           prop.SetValue(model, dr[PropertyName] is DBNull ? (object)null : Enum.Parse(targetType, Convert.ToString(dr[PropertyName]))); 
          else 
           prop.SetValue(model, dr[PropertyName] is DBNull ? (object)null : Convert.ChangeType(dr[PropertyName], targetType)); 
         } 
         catch (Exception ex) 
         { 
          //Logging.CustomLogging(loggingAreasType: LoggingAreasType.Class, loggingType: LoggingType.Error, className: CurrentClassName, methodName: MethodBase.GetCurrentMethod().Name, stackTrace: "There's some problem in converting model property name: " + PropertyName + ", model property type: " + targetType.ToString() + ", data row value: " + (dr[PropertyName] is DBNull ? string.Empty : Convert.ToString(dr[PropertyName])) + " | " + ex.StackTrace); 
          throw; 
         } 
        } 
       } 
       models.Add(model); 
      } 
      return models; 
     } 
Cuestiones relacionadas