Подтвердить что ты не робот

Как получить значение MemberInfo?

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

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

Спасибо!

4b9b3361

Ответ 1

Здесь пример полей, используя 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() - хотя вам также необходимо передать значения для любых параметров свойствам, (Для "нормальных" свойств С# не будет никаких свойств, но индексы индекса С# также считаются свойствами, которые относятся к структуре.) Для методов вам нужно вызвать Invoke, если вы хотите вызвать метод и использовать возвращаемое значение.

Ответ 2

Ответ Джона - это просто одно наблюдение: в рамках общего дизайна я бы:

  • обычно избегают непубличные участники.
  • избегать публичных полей (почти всегда)

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

Ответ 3

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

Ответ 4

В переносимой библиотеке классов, где свойство MemberType недоступно, используйте это:

public static object GetValue(this MemberInfo member, object obj)
{
    var field = member as FieldInfo;
    if (field != null)
      return field.GetValue(obj);
    var property = member as PropertyInfo;
    if (property != null)
      return property.GetValue(obj);

    throw new NotSupportedException($"The type '{member.GetType()}' is not supported.");
}