【问题标题】:How to tell if a PropertyInfo is of a particular enum type?如何判断 PropertyInfo 是否属于特定枚举类型?
【发布时间】:2009-10-08 23:08:12
【问题描述】:

我有以下代码:

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

当我到达Enum 类型的字段时,或者在本例中为NameSpace.MyEnum,我想做一些特别的事情。我不能简单地SetValue,因为来自数据库的值可以说是“m”,Enum 中的值是“Mr”。所以我需要调用另一种方法。我知道!旧系统对吗?

那么我如何确定PropertyInfo 项何时属于特定枚举类型?

所以在上面的代码中,我想首先检查PropertyInfo 类型是否属于特定枚举,如果是则调用我的方法,如果不是则简单地允许SetValue 运行。

【问题讨论】:

  • 不使用 Activator.CreateInstance(),只需将“new”约束添加到您的泛型:“where T : class, new()”。然后只需使用“T entity = new T()”。这样,您可以在编译时强制要求无参数构造函数。
  • @Brannon,谢谢,这是一个很好的提示。当我开始工作时会做。谢谢。

标签: c# enums propertyinfo


【解决方案1】:

这是我成功使用的方法

property.PropertyType.IsEnum

【讨论】:

  • 虽然这不能回答要求识别特定类型的枚举的原始问题,但这正是我正在寻找的。非常感谢。
【解决方案2】:

在你上面的代码中,

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

会告诉你当前类型是否(派生自)枚举。

【讨论】:

    【解决方案3】:
    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; }
    }
    

    【讨论】:

    • 测试 type == typeof(MyEnum) 可能更清楚。 IsAssignableTo 不会添加任何值,因为您不能从 MyEnum 派生其他类型。
    • 谢谢@Matthew。像买的一样工作。
    【解决方案4】:

    这是我将数据表转换为强类型列表时的处理方式

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      • 1970-01-01
      • 2015-02-14
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多