English 中文(简体)
我如何获取MemberInfo的值?
原标题:
  • 时间:2008-10-26 20:20:38
  •  标签:

我该如何获取MemberInfo对象的值?.Name返回变量的名称,但我需要值。

我认为您可以使用FieldInfo完成此操作,但我没有示例代码。如果您知道如何完成此操作,您能提供一下代码段吗?

谢谢!

问题回答

尽管我基本上同意马克关于不反映领域的观点,但有时是需要的。 如果您想反射成员并且不关心它是字段还是属性,可以使用此扩展方法获取该值(如果您想要类型而不是值,请参见 nawful 在此问题的答案):

    public static object GetValue(this MemberInfo memberInfo, object forObject)
    {
        switch (memberInfo.MemberType)
        {
            case MemberTypes.Field:
                return ((FieldInfo)memberInfo).GetValue(forObject);
            case MemberTypes.Property:
                return ((PropertyInfo)memberInfo).GetValue(forObject);
            default:
                throw new NotImplementedException();
        }
    } 

这里是使用 FieldInfo.GetValue 进行字段示例的示例:

using System;
using System.Reflection;

public class Test
{
    // public just for the sake of a short example.
    public int x;

    static void Main()
    {
        FieldInfo field = typeof(Test).GetField("x");
        Test t = new Test();
        t.x = 10;

        Console.WriteLine(field.GetValue(t));
    }
}

相似的代码也可以用于使用 PropertyInfo.GetValue() 的属性 – 虽然在这里你还需要传递属性的任何参数值。(对于“正常”的 C# 属性不会有这样的参数,但是对于框架而言,C# 索引器也被视为属性。)对于方法,如果你想要调用方法并使用返回值,你需要调用 Invoke

Jon的回答非常理想-只有一个观察:作为一般设计的一部分,我会:

  1. generally avoid reflecting against non-public members
  2. avoid having public fields (almost always)

这两个的结论是,通常情况下,您只需反射公共属性(除非您知道方法的作用,否则不应调用方法;属性获取器预期是幂等的[除了延迟加载])。因此,对于PropertyInfo,这只是prop.GetValue(obj, null);

实际上,我是System.ComponentModel的忠实粉丝,所以我会倾向于使用:

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

或者针对特定的财产:

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

System.ComponentModel的一个优点是它可以与抽象的数据模型一起工作,例如DataView将列公开为虚拟属性; 还有其他一些技巧(如性能技巧)。





相关问题