Cómo obtener un valor de propiedad basado en el nombre


154

¿Hay alguna forma de obtener el valor de una propiedad de un objeto en función de su nombre?

Por ejemplo si tengo:

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

y

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

Quiero escribir un método donde pueda pasar el nombre de la propiedad y devolvería el valor de la propiedad. es decir:

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

Respuestas:


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

18
Tenga en cuenta que, dado que utiliza la reflexión, es mucho más lento. Probablemente no sea un problema, pero es bueno estar al tanto.
Matt Greer

"No se puede convertir de String a BindingFlags"
Christine

6
¿Existe una forma "más rápida" de @MattGreer?
FizxMike

45

Tendrías que usar la reflexión

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

Si quieres ser realmente elegante, puedes convertirlo en un método de extensión:

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

Y entonces:

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

Querría GetValue en lugar de SetValue
Matt Greer

¿Puedo hacer esto también para un SetValue? ¿cómo?
Piero Alberto

2
cosa menor: el método de extensión probablemente no necesita tener la variable nombradacar
KyleMit

Para ver cómo establecer el valor de la propiedad, según una cadena propertyName, vea la respuesta aquí: Establecer el valor de las propiedades a través de la reflexión
nwsmith

35

Quieres reflejo

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

7
+1 Esta es la mejor respuesta ya que está mostrando todos los objetos intermedios
Matt Greer

1
En lugar de pasar el valor de la propiedad, ¿puedo pasar el índice y obtener el nombre y el valor de la propiedad (para poder recorrer toda la propiedad)?
singhswat

@singhswat Deberías hacer eso como una nueva pregunta.
Chuck Savage

7

Muestra simple (sin escribir código duro de reflexión en el cliente)

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

Además, otros chicos responden, es fácil obtener el valor de propiedad de cualquier objeto mediante el uso del método de extensión como:

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

    }

El uso es:

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

A partir de C # 6, puede usar la propagación nula return T.GetType().GetProperty(PropName)?.GetValue(T, null);
Alef Duarte

7

Ampliando la respuesta de Adam Rackis, podemos hacer que el método de extensión sea genérico simplemente así:

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

También puede lanzar un poco de manejo de errores si lo desea.


2

Para evitar la reflexión, puede configurar un diccionario con sus nombres de propiedad como teclas y funciones en la parte de valor del diccionario que devuelven los valores correspondientes de las propiedades que solicita.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.