C#でオブジェクトのすべてのパブリックフィールドを見つけるにはどうすればよいですか?
質問
ArrayList(おそらくオブジェクトでいっぱい)を取得し、ArrayList内の各オブジェクトのすべてのフィールド(およびその値)をリストするメソッドを構築しています。
現在、私のコードは次のとおりです。
public static void ListArrayListMembers(ArrayList list)
{
foreach (Object obj in list)
{
Type type = obj.GetType();
string field = type.GetFields().ToString();
Console.WriteLine(field);
}
}
もちろん、私はこのコードの直接の問題を理解しています。それが機能した場合、ArrayListのオブジェクトごとに1つのフィールドのみを印刷します。これは後で修正します-現在、オブジェクトに関連付けられているすべてのパブリックフィールドを取得する方法に興味があります。
解決
foreach (Object obj in list) {
Type type = obj.GetType();
foreach (var f in type.GetFields().Where(f => f.IsPublic)) {
Console.WriteLine(
String.Format("Name: {0} Value: {1}", f.Name, f.GetValue(obj));
}
}
このコードを使用するには.NET 3.5が必要です;-)
他のヒント
BindingFlagsを使用して、クラスで直接宣言されたすべてのオブジェクトフィールドを取得できます。
GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
および次のものを継承したものを含むすべてのオブジェクトフィールド:
GetFields(BindingFlags.Public | BindingFlags.Instance)
public static void ListArrayListMembers(ArrayList list)
{
foreach (Object obj in list)
{
Type type = obj.GetType();
Console.WriteLine("{0} -- ", type.Name);
Console.WriteLine(" Properties: ");
foreach (PropertyInfo prop in type.GetProperties())
{
Console.WriteLine("\t{0} {1} = {2}", prop.PropertyType.Name,
prop.Name, prop.GetValue(obj, null));
}
Console.WriteLine(" Fields: ");
foreach (FieldInfo field in type.GetFields())
{
Console.WriteLine("\t{0} {1} = {2}", field.FieldType.Name,
field.Name, field.GetValue(obj));
}
}
}
MSDN の状態:
戻り値- タイプ:System.Reflection.FieldInfo []
現在のタイプに定義されたすべてのパブリックフィールドを表すFieldInfoオブジェクトの配列。
もちろん、もう1つの質問は、「なぜパブリックフィールドがあるのですか?」です。 -プロパティが望ましい。抽象化として、リフレクションが唯一のオプションではないことに注意してください:実行時に型のプロパティをオンザフライで公開することも可能です(型指定されていない DataTable
/ DataView
は列をプロパティとして公開します。)
これをサポートするには(単純なオブジェクトもサポートします)、 TypeDescriptor
を使用します:
foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
{
Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
}
これにより、多数の拡張オプションも使用できます。たとえば、リフレクションの高速化 a>(コードを変更せずに)。
static void ListArrayListMembers(ArrayList list)
{
foreach (object obj in list)
{
Type type = obj.GetType();
foreach (FieldInfo field in type.GetFields(BindingFlags.Public))
{
Console.WriteLine(field.Name + " = " + field.GetValue(obj).ToString());
}
}
}