2009-10-08 11 views
9

J'ai le code suivant:Comment savoir si un PropertyInfo est d'un type enum particulier?

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

Quand je reçois un champ de type Enum, ou dans ce cas NameSpace.MyEnum, je veux faire quelque chose de spécial. Je ne peux pas simplement SetValue parce que la valeur provenant de la base de données est disons "m" et la valeur dans le Enum est "Mr". Donc j'ai besoin d'appeler une autre méthode. Je connais! Les systèmes hérités, n'est-ce pas?

Alors, comment déterminer quand un article PropertyInfo est d'un type d'énumération particulier? Donc, dans le code ci-dessus, je voudrais d'abord vérifier si le type PropertyInfo est d'un spécification et si elle est alors appeler ma méthode et si non alors laissez SetValue s'exécuter.

+1

Au lieu d'utiliser Activator.CreateInstance (), ajoutez simplement la "nouvelle" contrainte à votre générique: "où T: class, new()". Ensuite, utilisez simplement "T entity = new T()". De cette façon, vous pouvez imposer le besoin d'un constructeur sans paramètre à la compilation. – Brannon

+0

@Brannon, merci c'est un bon conseil. fera quand je me mets au travail. Merci. – griegs

Répondre

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

Il pourrait être plus clair juste pour tester le type == typeof (MyEnum). IsAssignableTo n'ajoute aucune valeur car vous ne pouvez pas avoir un autre type dérivé de MyEnum. – itowlson

+0

Merci @Matthew. Fonctionne comme un acheté. – griegs

3

Dans votre code ci-dessus,

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

vous obtiendrez si oui ou non le type de courant est (dérivé) ou non un ENUM.

+0

+1 Merci @adrianbanks pour votre contribution. – griegs

20

Voici ce que j'utilise avec succès

property.PropertyType.IsEnum 
0

Voici comment je gère quand je convertir une table de données dans une liste fortement typé

/// <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; 
     } 
Questions connexes