#.net #reflection #enums #nullable
Вопрос:
Как мне определить, действительно ли a Nullable(of Enum)
является an Enum
с помощью отражения?
Я работаю с методом, который динамически заполняет объект типа T
с IDataReader
помощью вызова, полученного из базы данных. По своей сути, он перебирает ординалы datareader, все свойства T
и заполняет свойства, соответствующие имени ординалов (также для изменения имен столбцов используется некоторая магия атрибутов). В любых других обстоятельствах это отлично работает, но когда я проверяю свойство BaseType
для System.Enum
, вместо этого я нахожу, что, System.ValueType
таким образом, моя проверка перечисления не выполняется, и метод взрывается.
[Правка: Type.IsEnum
не работает так, как мне нужно. Главная проблема здесь в том, что ничто в T
иерархии базовых типов не говорит о том, что это так Enum
. Это как будто превращение его в Nullable
тип лишает меня Enum
прав.]
Есть какие-нибудь идеи?
Ответ №1:
Это немного громоздко:
- Получить тип из
PropertyInfo.PropertyType
- Тест на
IsGenericType
- Если это так, получите универсальный тип с
GetGenericTypeDefinition()
- Если этот тип равен
typeof(Nullable<>)
, у вас есть значение, допускающее значение Null - Получите базовый (т. Е.
Enum
) тип сNullable.GetUnderlyingType(propertyInfo.PropertyType)
Комментарии:
1. Сегодня на работе я кое-что обдумал с типами COM. Вздох. Похоже, на самом деле не лучше с универсальными типами, даже несмотря на то, что они управляются 😉
2. Твердый ответ, мой друг. Вот инструкция if для этого : свойство var = [mytype]. GetType().getProperty([имя свойства]); если (свойство. Тип свойства. IsGenericType amp;amp; свойство. Тип свойства. GetGenericTypeDefinition() == тип(Обнуляемый<>) amp;amp; тип(Перечисление). IsAssignableFrom(Обнуляется. GetUnderlyingType(свойство. Тип свойства)))
Ответ №2:
Ваш вопрос неясен. Вы можете использовать .HasValue
, чтобы узнать, имеет ли значение Null перечисление или оно равно нулю, но, похоже, это не является целью вашего вопроса. Используете ли вы отражение для получения типа переменной и приведения данных IDataReader из объекта в этот тип?
Ответ №3:
Всегда ли столбец, возвращаемый из IDataReader, может быть обнулен? Если это так, то простым способом проверки может быть:
AnEnum? enumObj;
if (enumObj.HasValue)
{
enumObj.Value.GetType().IsEnum();
}
Надеюсь, это поможет.
Ответ №4:
Я тоже чувствую, что вопрос не совсем ясен. Я использовал трюк OregonGhost в нашем производственном коде. Это хорошо, когда список перечислений невелик, но может замедляться по мере роста иерархии (прочитайте более 100 записей).
Мне также нравится использовать цепочку значений перечисления, когда существует концепция, охватывающая несколько классов в иерархии наследования (например, перечисления, представляющие поля/свойства в классе).:
class Base
{
enum BaseEnum
{
Val1,
Val2,
LastVal
}
}
class Derived
{
enum DerivedEnum
{
Val3 = BaseEnum.LastVal,
Val4,
LastVal
}
}