C# 如何获取 MemberInfo 的值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/238555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:21:39  来源:igfitidea点击:

How do I get the value of MemberInfo?

c#reflection

提问by Keith Fitzgerald

How do I get the value of a MemberInfoobject? .Namereturns the name of the variable, but I need the value.

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

I think you can do this with FieldInfobut I don't have a snippet, if you know how to do this can you provide a snippet??

我想你可以做到这一点,FieldInfo但我没有一个片段,如果你知道如何做到这一点,你能提供一个片段吗?

Thanks!

谢谢!

回答by Jon Skeet

Here's an example for fields, using FieldInfo.GetValue:

这是使用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));
    }
}

Similar code will work for properties using PropertyInfo.GetValue()- although there you also need to pass the values for any parameters to the properties. (There won't be any for "normal" C# properties, but C# indexers count as properties too as far as the framework is concerned.) For methods, you'll need to call Invokeif you want to call the method and use the return value.

类似的代码适用于使用PropertyInfo.GetValue() 的属性- 尽管您还需要将任何参数的值传递给属性。(不会有任何的“正常” C#属性,但是C#索引器也尽可能的框架而言算作属性。)对于方法,您将需要调用调用,如果你要调用的方法和使用返回值。

回答by Marc Gravell

Jon's answer is ideal - just one observation: as part of general design, I would:

乔恩的回答是理想的——只是一个观察:作为总体设计的一部分,我会:

  1. generallyavoid reflecting against non-public members
  2. avoid having public fields (almost always)
  1. 一般避免反映非公开成员
  2. 避免使用公共字段(几乎总是)

The upshot of these two is that generallyyou only need to reflect against public properties (you shouldn't be calling methods unless you know what they do; property getters are expectedto be idempotent [lazy loading aside]). So for a PropertyInfothis is just prop.GetValue(obj, null);.

这两者的结果是,通常您只需要反映公共属性(除非您知道它们做什么,否则您不应该调用方法;​​属性 getter应该是幂等的 [懒惰加载一边])。所以对于一个PropertyInfo这只是prop.GetValue(obj, null);.

Actually, I'm a big fan of System.ComponentModel, so I would be tempted to use:

实际上,我是 的忠实粉丝System.ComponentModel,所以我很想使用:

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

or for a specific property:

或对于特定属性:

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

One advantage of System.ComponentModelis that it will work with abstracted data models, such as how a DataViewexposes columns as virtual properties; there are other tricks too (like performance tricks).

的一个优点System.ComponentModel是它可以使用抽象的数据模型,例如 a 如何DataView将列公开为虚拟属性;还有其他技巧(如表演技巧)。

回答by Eric Hewitt

Although I generally agree with Marc's point about not reflecting fields, there are times when it is needed. If you want to reflect a member and you don't care whether it is a field or a property, you can use this extension method to get the value (if you want the type instead of the value, see nawful's answer to this question):

尽管我大体上同意 Marc 关于不反映字段的观点,但有时也需要这样做。如果你想反映一个成员并且你不关心它是一个字段还是一个属性,你可以使用这个扩展方法来获取值(如果你想要类型而不是值,请参阅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();
        }
    }