2009-10-08 8 views
9

Tôi có đoạn mã sau:Làm cách nào để biết một PropertyInfo có thuộc loại enum cụ thể không?

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

Khi tôi nhận được vào một lĩnh vực loại Enum, hoặc trong trường hợp này NameSpace.MyEnum, tôi muốn làm một cái gì đó đặc biệt. Tôi không thể chỉ đơn giản là SetValue vì giá trị đến từ cơ sở dữ liệu là giả sử "m" và giá trị trong số Enum là "Mr". Vì vậy, tôi cần phải gọi một phương pháp khác. Tôi biết! Hệ thống cũ phải không?

Vậy làm cách nào để xác định thời điểm một mục PropertyInfo thuộc loại liệt kê cụ thể? Vì vậy, trong đoạn mã trên, tôi muốn kiểm tra xem loại PropertyInfo có thuộc loại specif hay không và nếu nó sau đó gọi phương thức của tôi và nếu không thì chỉ cần cho phép SetValue chạy.

+1

Thay vì sử dụng Activator.CreateInstance (), chỉ cần thêm ràng buộc "mới" vào generic của bạn: "trong đó T: class, new()". Sau đó, chỉ cần sử dụng "T entity = new T()". Bằng cách đó, bạn có thể thực thi sự cần thiết của một hàm tạo parameterless tại thời gian biên dịch. – Brannon

+0

@Brannon, cảm ơn đó là một mẹo tuyệt vời. sẽ làm gì khi tôi đi làm. cảm ơn. – griegs

Trả lời

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

Nó có thể được rõ ràng hơn chỉ để kiểm tra loại == typeof (MyEnum). IsAssignableTo không thêm bất kỳ giá trị nào vì bạn không thể có một kiểu khác xuất phát từ MyEnum. – itowlson

+0

Cảm ơn bạn @Matthew. Hoạt động giống như mua hàng. – griegs

3

Trong đoạn code trên của bạn,

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

sẽ giúp bạn có hay không loại hiện được (nguồn gốc từ) một enum hay không.

+0

+1 Cảm ơn @adrianbanks vì những đóng góp của bạn. – griegs

20

Đây là những gì tôi sử dụng với thành công

property.PropertyType.IsEnum 
0

Đây là cách tôi xử lý khi tôi chuyển đổi một bảng dữ liệu vào một danh sách mạnh mẽ gõ

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