12

I have the following code:

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

When I get to a field of type Enum, or in this case NameSpace.MyEnum, I want to do something special. I can't simply SetValue because the value coming from the database is let's say "m" and the value in the Enum is "Mr". So I need to call another method. I know! Legacy systems right?

So how do I determine when a PropertyInfo item is of a particular enumeration type?

So in the above code I'd like to first check whether the PropertyInfo type is of a specif enum and if it is then call my method and if not then simply allow SetValue to run.

bluish
  • 23,093
  • 23
  • 110
  • 171
griegs
  • 22,002
  • 28
  • 113
  • 201
  • 1
    Instead of using Activator.CreateInstance(), just add the "new" constraint to your generic: "where T : class, new()". Then just use "T entity = new T()". That way, you can enforce the need for a parameterless constructor at compile time. – Brannon Oct 09 '09 at 18:11
  • @Brannon, thanks that's a great tip. will do when i get into work. thanks. – griegs Oct 10 '09 at 19:53

4 Answers4

43

Here is what I use with success

property.PropertyType.IsEnum
Valamas
  • 22,332
  • 24
  • 97
  • 172
  • 2
    While this doesn't answer the original question which is asking to identify an enum of a particular type, this is exactly what I was looking for. Many thanks. – Mark McGookin Aug 17 '20 at 07:42
4

In your above code,

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

will get you whether or not the current type is (derived from) an enum or not.

adrianbanks
  • 76,725
  • 21
  • 166
  • 198
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; }
}
Matthew Whited
  • 21,248
  • 2
  • 48
  • 67
  • 2
    It might be clearer just to test type == typeof(MyEnum). IsAssignableTo doesn't add any value because you can't have another type deriving from MyEnum. – itowlson Oct 08 '09 at 23:18
  • Thank you @Matthew. Works like a bought one. – griegs Oct 08 '09 at 23:27
0

This is how I handle when I convert a data table into a strongly typed list

/// <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;
        }
Ajay Suwalka
  • 501
  • 1
  • 7
  • 22