Jak uzyskać wartość właściwości na podstawie nazwy


147

czy istnieje sposób na uzyskanie wartości właściwości obiektu na podstawie jego nazwy?

Na przykład, jeśli mam:

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

i

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

Chcę napisać metodę, w której mogę przekazać nazwę właściwości i zwróci wartość właściwości. to znaczy:

public string GetPropertyValue(string propertyName)
{
   return the value of the property;
}

Odpowiedzi:


310
return car.GetType().GetProperty(propertyName).GetValue(car, null);

17
Pamiętaj, że ponieważ wykorzystuje to odbicie, jest znacznie wolniejsze. Prawdopodobnie nie jest to problem, ale warto o tym wiedzieć.
Matt Greer

„Nie można przekonwertować elementu String na BindingFlags”
Christine,

5
Czy istnieje „szybszy” sposób @MattGreer?
FizxMike

44

Musiałbyś użyć refleksji

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

Jeśli chcesz być naprawdę fantazyjny, możesz uczynić z tego metodę rozszerzającą:

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

I wtedy:

string makeValue = (string)car.GetPropertyValue("Make");

Chciałbyś GetValue zamiast SetValue
Matt Greer

czy mogę to zrobić również dla SetValue? w jaki sposób?
Piero Alberto

1
drobna rzecz - metoda rozszerzenia prawdopodobnie nie musi mieć zmiennej o nazwiecar
KyleMit

Aby zobaczyć, jak ustawić wartość właściwości na podstawie ciągu propertyName, zobacz odpowiedź tutaj: Ustawianie wartości właściwości za pomocą odbicia
nwsmith

35

Chcesz odbicia

Type t = typeof(Car);
PropertyInfo prop = t.GetProperty("Make");
if(null != prop)
return prop.GetValue(this, null);

7
+1 To najlepsza odpowiedź, ponieważ pokazujesz wszystkie obiekty pośrednie
Matt Greer

1
Zamiast przekazywać wartość właściwości, czy mogę przekazać indeks i uzyskać nazwę właściwości i wartość (dzięki czemu mogę przejść przez całą właściwość)?
singhswat

@singhswat Powinieneś zadać to jako nowe pytanie.
Chuck Savage,

7

Prosty przykład (bez zapisu twardego kodu odbicia w kliencie)

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

7

Ponadto inni faceci odpowiadają, jego łatwe do uzyskania wartości właściwości dowolnego obiektu za pomocą metody rozszerzenia, takiej jak:

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

    }

Wykorzystanie to:

Car foo = new Car();
var balbal = foo.GetPropertyValue("Make");

7

Rozwijając odpowiedź Adama Rackisa - możemy uczynić metodę rozszerzenia ogólną po prostu w ten sposób:

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

Jeśli chcesz, możesz też rzucić na to trochę obsługi błędów.


1

Aby uniknąć refleksji, możesz skonfigurować słownik z nazwami właściwości jako kluczami i funkcjami w części słownikowej wartości, które zwracają odpowiednie wartości z żądanych właściwości.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.