リフレクションで定数を取得する
リフレクションで定数を取得したかったのですが、調べてもなかなか見つからなくて苦労したので覚書です。
同じく探している人の目に留まれば幸いです。
IsLiteral プロパティを参照する
定数は FieldInfo
オブジェクトの IsLiteral
プロパティ が true
になるので、これを参照すれば定数が取得可能です。
// Constants クラスの定数を取得する
foreach (FieldInfo field in typeof(Constants).GetFields(BindingFlags.Public | BindingFlags.Static))
{
if (field.IsLiteral)
{
Console.WriteLine($"{field.Name}:{field.FieldType.Name}:{field.GetRawConstantValue()}");
}
}
始めに、定数が含まれているクラス(例ではConstants
) から GetFields
メソッド で public
かつ static
なフィールドを取得し、その中で IsLiteral
プロパティ が true
となっているものだけを抽出するだけでした。
定数の値は FieldInfo
オブジェクトの GetRawConstantValue
メソッド で取得できます(object?
型になるので、必要に応じてキャストが必要です)。
(これだけのことを調べるのに結構な時間かかってしまいました……)
おまけ サブクラスを含む定数クラスから全ての文字列定数を列挙する
以下のようなメソッドを作りたくて調べてました。
あまり必要なケースは無いと思いますが、必要な方の参考になりましたら。
指定したクラスとそのサブクラスに含まれている文字列定数を全て列挙し、Key = 定数名(識別子名)、Value = 定数値(文字列) となるディクショナリを返すメソッドです。
private static Dictionary<string, string> CreateConstantsDictionary(Type type)
{
return type.GetFields(BindingFlags.Public | BindingFlags.Static)
.Concat(
type.GetNestedTypes()
.SelectMany(sub => sub.GetFields(BindingFlags.Public | BindingFlags.Static))
)
.Where(field => field.IsLiteral)
.Where(field => field.FieldType == typeof(string))
.ToDictionary(
field => field.Name,
field => (string)field.GetRawConstantValue()!
);
}