【问题标题】:How can I find all the public fields of an object in C#?如何在 C# 中找到对象的所有公共字段?
【发布时间】:2010-09-19 05:35:10
【问题描述】:

我正在构造一个方法来接收一个 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 中为每个对象打印一个字段。我稍后会解决这个问题 - 现在我只是好奇如何获取与对象关联的所有公共字段。

【问题讨论】:

  • 你的代码会打印出这个:System.Reflection.FieldInfo[]

标签: c# object field public


【解决方案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 才能工作;-)

【讨论】:

  • 没关系。我更喜欢这种技术。我也可以推断出这个来获取属性(甚至方法)。非常感谢!
  • 感谢 .where 条件 Dave.. 我知道这是 10 年后,但我喜欢它。直截了当.. 只有公众.. 不需要 getsetters.. 并且不用担心它仍然适用于 VS 2017 .net 4.6.2 和核心中的 c#:p
  • 请注意 type.GetFields() 总是只获取公共字段,因此不需要过滤公共字段。
【解决方案2】:

可以通过BindingFlags直接获取类中声明的所有对象Field:

GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)

以及所有对象字段,包括继承于:

GetFields(BindingFlags.Public | BindingFlags.Instance)

【讨论】:

    【解决方案3】:
    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 定义的 type.GetFields() 状态:

    返回值 - 类型:System.Reflection.FieldInfo[]

    FieldInfo 对象数组,表示为当前类型定义的所有公共字段

    【讨论】:

      【解决方案4】:

      当然,另一个问题是“为什么你有公共领域?” - 属性更可取。作为抽象,请注意反射不是唯一的选择:类型也可以在运行时即时公开其属性(例如无类型的DataTable/DataView 如何将列公开为属性)。

      要支持这一点(同时也支持简单对象),您可以使用TypeDescriptor

              foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
              {
                  Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
              }
      

      这还允许许多可扩展性选项 - 例如,极大地speeding up reflection(无需更改任何代码)。

      【讨论】:

      • 漂亮。这允许我为一个抽象超类创建一个通用的 ToString(),它显示了它的大多数子类包含的两个属性(“Key”和“Code” - 是一个数据库对象类),而不需要关于所述子类的任何特定信息 :)
      【解决方案5】:
          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());
                  }
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-03
        • 1970-01-01
        • 2011-07-17
        • 2010-11-15
        • 2016-07-19
        相关资源
        最近更新 更多