Como obter um valor de propriedade com base no nome

147

existe uma maneira de obter o valor de uma propriedade de um objeto com base em seu nome?

Por exemplo, se eu tiver:

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

e

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

Eu quero escrever um método onde eu possa passar o nome da propriedade e ele retornaria o valor da propriedade. ou seja:

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

Respostas:

310
return car.GetType().GetProperty(propertyName).GetValue(car, null);
Matt Greer
fonte
17
Lembre-se de que, como isso usa reflexão, é muito mais lento. Provavelmente não é um problema, mas é bom estar ciente.
Matt Greer
"Não é possível converter de String para BindingFlags"
Christine
5
Existe uma maneira "mais rápida" do @MattGreer?
FizxMike
44

Você teria que usar reflexão

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

Se você quer ser realmente chique, pode torná-lo um método de extensão:

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

E depois:

string makeValue = (string)car.GetPropertyValue("Make");
Adam Rackis
fonte
Você gostaria GetValue vez de SetValue
Matt Greer
posso fazer isso também para um SetValue? como?
Piero Alberto
1
menor coisa- método de extensão provavelmente não precisa ter a variável chamadacar
KyleMit
Para ver como definir o valor da propriedade, com base em uma corda propertyName, ver a resposta aqui: Definir o valor de propriedades através da reflexão
nwsmith
35

Você quer Reflexão

Type t = typeof(Car);
PropertyInfo prop = t.GetProperty("Make");
if(null != prop)
return prop.GetValue(this, null);
Chuck Savage
fonte
7
1 Esta é a melhor resposta que você está mostrando todos os objetos intermediários
Matt Greer
1
Em vez de passar o valor da propriedade, posso passar o índice e obter o nome e o valor da propriedade (para que eu possa percorrer toda a propriedade)?
Singhswat 4/10
@singhswat Você deve fazer isso como uma nova pergunta.
Chuck Savage
7

Amostra simples (sem código rígido de reflexão de gravação no 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"));
    }
Harveyt
fonte
7

Além disso, outros caras respondem: é fácil obter o valor da propriedade de qualquer objeto usando o método Extension, 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);
        }

    }

O uso é:

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

Expandindo a resposta de Adam Rackis - podemos tornar o método de extensão genérico da seguinte maneira:

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

Você também pode usar algum tratamento de erros, se quiser.

Cameron Atacante
fonte
1

Para evitar a reflexão, você pode configurar um Dicionário com seus nomes de propriedade como chaves e funções na parte do valor do dicionário que retorna os valores correspondentes das propriedades solicitadas.

Paul McCarthy
fonte