Как я могу получить значение MemberInfo? - PullRequest
30 голосов
/ 26 октября 2008

Как получить значение объекта MemberInfo? .Name возвращает имя переменной, но мне нужно значение.

Я думаю, что вы можете сделать это с FieldInfo, но у меня нет фрагмента, если вы знаете, как это сделать, вы можете предоставить фрагмент ??

Спасибо!

Ответы [ 3 ]

32 голосов
/ 26 октября 2008

Вот пример для полей, используя 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 , если вы хотите вызовите метод и используйте возвращаемое значение.

21 голосов
/ 31 октября 2015

Хотя я в целом согласен с мнением Марка о том, чтобы не отражать поля, бывают моменты, когда это необходимо. Если вы хотите отразить член, и вам все равно, является ли оно полем или свойством, вы можете использовать этот метод расширения, чтобы получить значение (если вы хотите, чтобы тип вместо значения, см. Ответ 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();
        }
    } 
11 голосов
/ 27 октября 2008

Ответ Джона идеален - только одно замечание: как часть общего плана я бы:

  1. обычно избегать отражения непубличные участники
  2. избегать открытых полей (почти всегда)

Результатом этих двух явлений является то, что , как правило, , вам нужно только отражать общие свойства (вы не должны вызывать методы, если не знаете, что они делают; методы получения свойств ожидаются быть идемпотентом [отложенная загрузка]). Так что для 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 представляет столбцы как виртуальные свойства; есть и другие приемы (например, приемы повышения производительности ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...