リフレクションを使用した.NET動的オブジェクト
-
08-07-2019 - |
質問
リフレクションを使用してNullable(of Enum)
が実際にEnum
であるかどうかを判断するにはどうすればよいですか?
データベース呼び出しから取得したT
を使用して、IDataReader
型のオブジェクトを動的に設定するメソッドを使用しています。本質的には、データリーダーの序数、およびBaseType
のすべてのプロパティをループ処理し、序数の名前に一致するプロパティを設定します(列名を変更するために属性マジックもスローされます)。他のすべての状況では、それはうまく機能しますが、プロパティのSystem.Enum
をチェックしてSystem.ValueType
の代わりにType.IsEnum
を見つけると、Nullable
したがって、Enumチェックが失敗し、メソッドが爆弾になります。
[編集: <=>は、私が必要とする方法では機能しません。ここでの主な問題は、<=>のBaseType階層内で<=>であると言っているものがないことです。 <=>タイプにすると、私の<=>権利は失われます。]
アイデアはありますか
解決
少し面倒です:
-
PropertyInfo.PropertyType
からタイプを取得
-
IsGenericType
のテスト
- もしそうなら、
GetGenericTypeDefinition()
でジェネリック型を取得します
- そのタイプが
typeof(Nullable<>)
に等しい場合、Nullableがあります - 基礎となる(つまり
Enum
)タイプをNullable.GetUnderlyingType(propertyInfo.PropertyType)
で取得する
他のヒント
あなたの質問は不明です。 .HasValue
を使用して、NullableにEnumがあるか、nullであるかを確認できますが、それは質問の目的ではないようです。リフレクションを使用して変数の型を取得し、IDataReaderのデータをObjectからその型にキャストしていますか?
IDataReaderから返される列は常にNullableですか?その場合、チェックする簡単な方法は次のとおりです。
AnEnum? enumObj;
if (enumObj.HasValue)
{
enumObj.Value.GetType().IsEnum();
}
役立つこと。
私も、質問が正確に明確ではないと感じています。 OregonGhostのトリックを製品コードで使用しました。 Enumのリストが小さい場合は良いのですが、階層が大きくなると(100エントリを超えて読むと)遅くなる可能性があります。
また、継承階層内の複数のクラスにまたがる概念がある場合、列挙値チェーンを使用することも好きです(クラスのフィールド/プロパティを表す列挙など):
class Base
{
enum BaseEnum
{
Val1,
Val2,
LastVal
}
}
class Derived
{
enum DerivedEnum
{
Val3 = BaseEnum.LastVal,
Val4,
LastVal
}
}