Как получить значение свойства на основе имени

148

Есть ли способ получить значение свойства объекта на основе его имени?

Например, если у меня есть:

public class Car : Vehicle
{
   public string Make { get; set; }
}

и

var car = new Car { Make="Ford" };

Я хочу написать метод, в котором я могу передать имя свойства, и оно будет возвращать значение свойства. то есть:

public string GetPropertyValue(string propertyName)
{
   return the value of the property;
}
Кодер 2
источник

Ответы:

311
return car.GetType().GetProperty(propertyName).GetValue(car, null);
Мэтт Грир
источник
17
Имейте в виду, что, поскольку это использует отражение, оно намного медленнее. Вероятно, не проблема, но хорошо знать.
Мэтт Грир
«Невозможно преобразовать строку в BindingFlags»
Кристина,
5
Есть ли более быстрый способ @MattGreer?
FizxMike
44

Вы должны использовать отражение

public object GetPropertyValue(object car, string propertyName)
{
   return car.GetType().GetProperties()
      .Single(pi => pi.Name == propertyName)
      .GetValue(car, null);
}

Если вы хотите быть по-настоящему модным, вы можете сделать это методом расширения:

public static object GetPropertyValue(this object car, string propertyName)
{
   return car.GetType().GetProperties()
      .Single(pi => pi.Name == propertyName)
      .GetValue(car, null);
}

А потом:

string makeValue = (string)car.GetPropertyValue("Make");
Адам Рэкис
источник
Вы бы хотели GetValue вместо SetValue
Мэтт Грир
я могу сделать это также для SetValue? как?
Пьеро Альберто
1
второстепенный метод расширения, вероятно, не должен иметь переменную с именемcar
KyleMit
Чтобы узнать, как установить значение свойства на основе строки propertyName, см. Ответ здесь: Установка значения свойств с помощью отражения
nwsmith
35

Вы хотите отражение

Type t = typeof(Car);
PropertyInfo prop = t.GetProperty("Make");
if(null != prop)
return prop.GetValue(this, null);
Чак Сэвидж
источник
7
+1 Это лучший ответ, поскольку вы показываете все промежуточные объекты
Мэтт Грир,
1
Вместо передачи значения свойства я могу передать индекс и получить имя и значение свойства (чтобы я мог просмотреть все свойства)?
Singhswat
@singhswat Вы должны задать это как новый вопрос.
Чак Сэвидж
7

Простой пример (без записи отражения жесткого кода в клиенте)

class Customer
{
    public string CustomerName { get; set; }
    public string Address { get; set; }
    // approach here
    public string GetPropertyValue(string propertyName)
    {
        try
        {
            return this.GetType().GetProperty(propertyName).GetValue(this, null) as string;
        }
        catch { return null; }
    }
}
//use sample
static void Main(string[] args)
    {
        var customer = new Customer { CustomerName = "Harvey Triana", Address = "Something..." };
        Console.WriteLine(customer.GetPropertyValue("CustomerName"));
    }
harveyt
источник
7

Кроме того, другие ребята отвечают, легко получить значение свойства любого объекта с помощью метода Extension, например:

public static class Helper
    {
        public static object GetPropertyValue(this object T, string PropName)
        {
            return T.GetType().GetProperty(PropName) == null ? null : T.GetType().GetProperty(PropName).GetValue(T, null);
        }

    }

Использование это:

Car foo = new Car();
var balbal = foo.GetPropertyValue("Make");
Али
источник
7

Расширяя ответ Адама Ракиса - мы можем сделать метод расширения универсальным просто так:

public static TResult GetPropertyValue<TResult>(this object t, string propertyName)
{
    object val = t.GetType().GetProperties().Single(pi => pi.Name == propertyName).GetValue(t, null);
    return (TResult)val;
}

Если хотите, вы можете обойти это и обработкой ошибок.

Кэмерон Форвард
источник
1

Чтобы избежать размышлений, вы можете установить словарь с вашими именами свойств в качестве ключей и функций в части значений словаря, которые возвращают соответствующие значения из запрошенных вами свойств.

Пол Маккарти
источник