Как определить, имеет ли PropertyInfo определенный тип перечисления?
у меня есть следующий код:
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
"Мистер". Поэтому мне нужно вызвать другой метод. Я знаю! Унаследованные системы, верно?
Итак, как мне определить, когда PropertyInfo
элемент имеет определенный тип перечисления?
поэтому в приведенном выше коде я хотел бы сначала проверьте, есть ли PropertyInfo
тип имеет перечисление specif, и если это, то вызовите мой метод, а если нет, то просто позвольте SetValue
запустить.
4 ответов
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; }
}
в вышеприведенном коде
bool isEnum = typeof(Enum).IsAssignableFrom(typeof(genericType));
получит вас независимо от того, является ли текущий тип (производным от) перечисления или нет.
вот как я обрабатываю, когда я преобразую таблицу данных в строго типизированный список
/// <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;
}