【问题标题】:How do I get the value of MemberInfo?如何获取 MemberInfo 的值?
【发布时间】:2008-10-26 20:20:38
【问题描述】:

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

我认为您可以使用FieldInfo 来完成此操作,但我没有 sn-p,如果您知道如何操作,您可以提供一个 sn-p 吗??

谢谢!

【问题讨论】:

    标签: c# reflection


    【解决方案1】:

    虽然我大体上同意 Marc 关于不反映字段的观点,但有时需要它。如果你想反映一个成员并且你不在乎它是一个字段还是一个属性,你可以使用这个扩展方法来获取值(如果你想要类型而不是值,请参阅nawful对@987654321的回答@ ):

        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();
            }
        } 
    

    【讨论】:

    • 对我来说比最佳答案好得多
    • 您也可以为此使用类型开关,以简化 ` switch (memberInfo) { case FieldInfo fieldInfo: return fieldInfo.GetValue(forObject); case PropertyInfo propertyInfo: return propertyInfo.GetValue(forObject);默认值:抛出新的 NotImplementedException(); }` 编辑:对于丑陋的格式感到抱歉
    【解决方案2】:

    这是一个使用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 - 你能举一个以 MemberInfo 对象开头的例子吗?
    • 什么样的? MemberInfos 可以是属性、字段、方法、事件或其他类型。你不能以同样的方式对待他们。例如,嵌套类型的“值”是什么?也许你应该告诉我们更多关于你的问题。
    • 太糟糕了 GetValue/SetValue 不是可以检查的接口。
    • @user295190, System.Reflection.BindingFlags var propeties = MyObject.GetType().GetProperties(BindingFlags.GetProperty & BindingFlags.SetProperty)
    • 关于我现在无法编辑的已发表评论......当然,这些是标志枚举,人们会在......上使用位运算符......
    【解决方案3】:

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

    1. 一般避免反省 非公开成员
    2. 避免使用公共字段(几乎总是)

    这两者的结果是通常您只需要针对公共属性进行反射(除非您知道它们的作用,否则您不应该调用方法;​​属性获取器是预期的 em> 是幂等的[懒加载一边])。所以对于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 如何将列公开为虚拟属性;还有其他技巧(例如performance tricks)。

    【讨论】:

    • 这被证明对我的场景非常有效,因为我必须使用属性并在对象上调用 GetField() 一直返回 null。谢谢你。
    • 啊,就是这样。。我只能模糊地记得在反射命名空间之外存在另一种方法:MemberInfoPropertyInfo..PropertyDescriptor 和我一样很好地服务于我当前的目的'我在我的实例中使用INotifyPropertyChanged...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 2021-10-24
    相关资源
    最近更新 更多