.NET Dynamic Objects with Reflection
-
08-07-2019 - |
Question
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?
Solution
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 withNullable.GetUnderlyingType(propertyInfo.PropertyType)
OTHER TIPS
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?
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.
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
}
}