2009-10-08 3 views
9

Ich habe den folgenden Code:Wie kann man sagen, wenn ein Property eines bestimmten Aufzählungstyp ist?

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

Wenn ich zu einem Feld des Typs erhalten Enum, oder in diesem Fall NameSpace.MyEnum, möchte ich etwas Besonderes tun. Ich kann nicht einfach SetValue, weil der Wert aus der Datenbank kommen, ist sagen wir mal „m“ und den Wert in der Enum ist „Herr“. Also muss ich eine andere Methode aufrufen. Ich kenne! Legacy-Systeme richtig?

Wie kann ich feststellen, wenn ein PropertyInfo Element eines bestimmten Aufzählungstyp ist?

Also im obigen Code möchte ich zuerst überprüfen, ob der PropertyInfo Typ ist eine Spezifikation und wenn es dann meine Methode aufrufen und wenn nicht, dann einfach SetValue ausführen lassen.

+1

Statt mit Activator.CreateInstance () umwandeln, fügen Sie einfach den „neuen“ Zwang zu Ihrem generic: „where T: Klasse, neu()“. Dann benutze einfach "T entity = new T()". Auf diese Weise können Sie die Notwendigkeit eines parameterlosen Konstruktors zum Zeitpunkt der Kompilierung erzwingen. – Brannon

+0

@Brannon, Dank, dass ein guter Tipp ist. werde tun, wenn ich in Arbeit komme. Vielen Dank. – griegs

Antwort

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

Es könnte klarer sein, nur um type == typeof (MyEnum) zu testen. IsAssignableTo fügt keinen Wert hinzu, da kein anderer Typ von MyEnum abgeleitet werden kann. – itowlson

+0

Danke @Matthew. Funktioniert wie ein gekaufter. – griegs

3

In Ihrem obigen Code

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

erhalten Sie, ob der aktuelle Typ ist (abgeleitet von) eine Enumeration oder nicht.

+0

+1 Danke @adrianbanks für Ihren Beitrag. – griegs

20

Hier ist, was ich mit Erfolg verwenden

property.PropertyType.IsEnum 
0

Dies ist, wie ich handhaben, wenn ich eine Datentabelle in eine stark typisierte Liste

/// <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; 
     } 
Verwandte Themen