Como saber se uma propriedadeInfo é de um tipo de enumeração específico?
-
20-09-2019 - |
Pergunta
Eu tenho o seguinte código:
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;
}
}
Quando chego a um campo do tipo Enum
, ou neste caso NameSpace.MyEnum
, Eu quero fazer algo especial. Eu não posso simplesmente SetValue
Porque o valor proveniente do banco de dados é digamos "m" e o valor no Enum
é "sr". Então, eu preciso chamar outro método. Eu sei! Sistemas Legados, certo?
Então, como faço para determinar quando um PropertyInfo
O item é de um tipo de enumeração específico?
Então, no código acima, eu gostaria de verificar primeiro se o PropertyInfo
O tipo é de um enume SetValue
para correr.
Solução
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; }
}
Outras dicas
Aqui está o que eu uso com sucesso
property.PropertyType.IsEnum
No seu código acima,
bool isEnum = typeof(Enum).IsAssignableFrom(typeof(genericType));
você conseguirá se o tipo atual é ou não (derivado) de uma enumeração ou não.
É assim que eu lidar quando converso uma tabela de dados em uma lista fortemente digitada
/// <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;
}