views:

765

answers:

4

How do I determine if a Nullable(of Enum) is indeed an Enum by means of reflection?

I'm working with a method that dynamically populates an object of type T with an IDataReader retrieved from a database call. At its essence, it loops through the datareader's ordinals, and all the properties of T and populates the properties that match the name of the ordinals (also some attribute magic is thrown to change column names). In every other circumstance, it works great, but when I check the property's BaseType for System.Enum I find instead, System.ValueType Thusly, my Enum check fails and the method bombs.

[Edit: Type.IsEnum doesn't work how I need it. The main issue here, is that nothing in T's BaseType hierarchy says that it is an Enum. It's as if making it a Nullable type forfeits my Enum rights.]

Any ideas?

+6  A: 

It's a bit cumbersome:

  • Get type from PropertyInfo.PropertyType
  • Test for IsGenericType
  • If it is, get the generic type with GetGenericTypeDefinition()
  • If that type equals typeof(Nullable<>), you have a Nullable
  • Get the underlying (i.e. Enum) type with Nullable.GetUnderlyingType(propertyInfo.PropertyType)
OregonGhost
Today at work, I did some Reflection things with COM types. Sigh. Seems to be not really better with generic types, even though they're managed ;)
OregonGhost
Merritt
A: 

Your question is unclear. You can use .HasValue to find if the Nullable has an Enum or it's null but that doesn't seem to be the purpose of your question. Are you using reflection to get the type of a variable and casting the IDataReader's data from Object to that type?

Dan Goldstein
A: 

Is the column that comes back from the IDataReader always a Nullable? If so, a simple way to check might be:

AnEnum? enumObj;
if (enumObj.HasValue)
{
  enumObj.Value.GetType().IsEnum();
}

Hope that helps.

Zachary Yates
A: 

I too feel that the question is not exactly clear. I've used OregonGhost's trick in our production code. It's good when the list of Enums is small, but can get slow as hierarchy grows (read beyond 100 entries).

I also like to use Enum value chaining when there is a concept that spans multiple classes in an inheritance hierarchy (such as enums representing fields/properties in a class):

class Base
{
  enum BaseEnum
  {
   Val1,
   Val2,
   LastVal
  }
}

class Derived
{
  enum DerivedEnum
  {
    Val3 = BaseEnum.LastVal,
    Val4,
    LastVal
  }
}
GregC