我正在构建一个方法来接收一个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中为每个对象打印一个字段。我稍后会解决这个问题 - 现在我只是好奇如何获取与对象相关的所有公共字段。
答案 0 :(得分:26)
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才能工作; - )
答案 1 :(得分:7)
您可以使用BindingFlags获取在类中直接声明的所有对象字段:
GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
和所有对象字段包括继承:
GetFields(BindingFlags.Public | BindingFlags.Instance)
答案 2 :(得分:4)
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));
}
}
}
我想提一下,在字段中查找IsPublic不是必需的。MSDN所定义的类型.GetFields():
返回值 - 键入:System.Reflection.FieldInfo []
表示为当前Type定义的所有公共字段的FieldInfo对象数组。
答案 3 :(得分:3)
当然,另一个问题是“为什么你有公共领域?” - 物业更可取。作为一个抽象,请注意反射不是唯一的选择:类型也可以在运行时即时公开它的属性(就像无类型DataTable
/ DataView
暴露列一样作为属性)。
为了支持这一点(同时也支持简单对象),您可以使用TypeDescriptor
:
foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
{
Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
}
这也允许多种可扩展性选项 - 例如,大量speeding up reflection(不更改任何代码)。
答案 4 :(得分:1)
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());
}
}
}