Como obter o valor de uma propriedade pelo nome através de reflexão em C#: análise para iniciantes
\n\nImagine a situação: você está escrevendo um código onde precisa acessar dinamicamente, em tempo real, uma propriedade de um objeto. O nome dessa propriedade vem, por exemplo, de um arquivo de configuração, de uma requisição JSON ou é inserido pelo usuário. Não é possível definir rigidamente objeto.NomeDaPropriedade — você não sabe o nome antecipadamente. O que fazer?
A solução é a reflexão (reflection) — um mecanismo poderoso do C# que permite inspecionar tipos de dados e seus membros (propriedades, métodos, campos) durante a execução do programa. Neste artigo, vamos abordar a pergunta mais popular no Stack Overflow: como obter o valor de uma propriedade de um objeto por uma string contendo seu nome. Vamos analisar com exemplos reais, do simples ao complexo, e considerar as armadilhas comuns que os iniciantes enfrentam.
\n\nO que é reflexão e para que serve?
\n\nReflexão em C# é a capacidade de um programa "olhar para si mesmo" e obter informações sobre seus próprios tipos. O namespace System.Reflection fornece classes como Type, PropertyInfo, MethodInfo, que permitem:
- \n
- Descobrir todas as propriedades e métodos de uma classe. \n
- Criar instâncias de classes sem o operador
new. \n - Chamar métodos e obter/definir valores de propriedades pelos seus nomes em string. \n
Sem reflexão, você não poderia, por exemplo, escrever um mapeador universal de objetos (como o AutoMapper) ou um serializador que funcione com qualquer tipo de dado.
\n\nExemplo básico: obtendo o valor de uma propriedade pelo nome
\n\nSuponha que temos uma classe simples Person:
public class Person\n{\n public string Name { get; set; }\n public int Age { get; set; }\n public string City { get; set; }\n}\n\nQueremos escrever um método que recebe um objeto Person e uma string com o nome da propriedade (por exemplo, "Name" ou "Age") e retorna o valor dessa propriedade. Veja como fazer isso com reflexão:
using System;\nusing System.Reflection;\n\npublic static object GetPropertyValue(object obj, string propertyName)\n{\n if (obj == null) throw new ArgumentNullException(nameof(obj));\n if (string.IsNullOrEmpty(propertyName)) throw new ArgumentException("O nome da propriedade não pode estar vazio", nameof(propertyName));\n\n // Obtém o tipo do objeto\n Type type = obj.GetType();\n\n // Obtém informações sobre a propriedade pelo nome\n PropertyInfo propertyInfo = type.GetProperty(propertyName);\n\n // Verifica se a propriedade existe\n if (propertyInfo == null)\n throw new ArgumentException($"Propriedade '{propertyName}' não encontrada no tipo '{type.Name}'");\n\n // Obtém o valor da propriedade\n return propertyInfo.GetValue(obj);\n}\n\nAgora usamos nosso método:
\n\nvar person = new Person { Name = "Ana", Age = 30, City = "São Paulo" };\n\nstring name = (string)GetPropertyValue(person, "Name");\nint age = (int)GetPropertyValue(person, "Age");\n\nConsole.WriteLine($"Nome: {name}, Idade: {age}"); // Saída: Nome: Ana, Idade: 30\n\nFunciona! Pontos-chave:
\n- \n
obj.GetType()— obtém o objetoTypeque descreve o tipo do nosso objeto. \n type.GetProperty("Name")— procura uma propriedade pública com o nome "Name". RetornaPropertyInfoounullse a propriedade não for encontrada. \n propertyInfo.GetValue(obj)— retorna o valor dessa propriedade para a instância específicaobj. \n
Nuances importantes e erros comuns (o que os juniores não contam)
\n\n1. Sensibilidade a maiúsculas/minúsculas
\nO método GetProperty por padrão diferencia maiúsculas de minúsculas. Se você especificar "name" em vez de "Name", a propriedade não será