2009-10-08 9 views
9

Mam następujący kod:Jak określić, czy właściwość PropertyInfo ma określony typ wyliczeniowy?

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

Kiedy się do pola typu Enum, lub w tym przypadku NameSpace.MyEnum, chcę zrobić coś specjalnego. Nie mogę po prostu SetValue, ponieważ wartość pochodząca z bazy danych to np. "M", a wartość w Enum to "Mr". Muszę więc zadzwonić inną metodą. Wiem! Starsze systemy w porządku?

Jak ustalić, czy pozycja PropertyInfo jest określonego typu wyliczenia?

Tak więc w powyższym kodzie chciałbym najpierw sprawdzić, czy typ PropertyInfo jest specyficzny i jeśli jest to wtedy zadzwoń do mojej metody, a jeśli nie, po prostu pozwól, aby uruchomił się SetValue.

+1

Zamiast Activator.CreateInstance (), po prostu dodaj "nowe" ograniczenie do twojego generycznego: "where T: class, new()". Następnie użyj "T entity = new T()". W ten sposób można wymusić konieczność konstruktora bez parametrów w czasie kompilacji. – Brannon

+0

@Brannon, dziękuję, to świetna wskazówka. zrobię, kiedy wejdę do pracy. dzięki. – griegs

Odpowiedz

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

To może być czystsze po prostu testować typ == typeof (MyEnum). IsAssignableTo nie dodaje żadnej wartości, ponieważ nie można mieć innego typu pochodzącego z MyEnum. – itowlson

+0

Dziękuję @Matthew. Działa jak kupiony. – griegs

3

W swojej powyższym kodzie

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

będzie Ci czy aktualny typ (pochodzący z) enum czy nie.

+0

+1 Dzięki @adrianbanks za Twój wkład. – griegs

20

Oto co mogę użyć z powodzeniem

property.PropertyType.IsEnum 
0

To jak sobie radzić, gdy przekonwertować tabelę danych do silnie typami listy

/// <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; 
     } 
Powiązane problemy