A reflexão em C# permite a manipulação dinâmica de campos em tipos durante a execução do programa. Este recurso é útil para cenários como mapeamento de dados ou injeção de dependências. A seguir, demonstra-se como acessar e modificar campos públicos de uma classe usando a classe System.Reflection.FieldInfo.
Considere uma classe simples com campos públicos:
public class Produto
{
public string Descricao;
public decimal Preco;
}
Produto item = new Produto();
Para definir os valores dos campos Descricao e Preco via reflexão, obtém-se primeiro o tipo do objeto e as metadados dos campos:
using System.Reflection;
Tipo tipoDoObjeto = item.GetType();
InfoCampo infoDescricao = tipoDoObjeto.GetCampo("Descricao");
InfoCampo infoPreco = tipoDoObjeto.GetCampo("Preco");
infoDescricao.DefinirValor(item, "Notebook");
infoPreco.DefinirValor(item, 2999.99m);
É crucial garantir a correspondência de tipos ao atribuir valores; caso contrário, uma exceção TargetInvocationException será lançada em tempo de execução. Por exemplo, tentar atribuir uma string a um campo decimal resultará em erro.
Para simplificar operações repetitivas, pode-se encapsular a lógica em uma classe auxiliar. O código abaixo mostra uma implementação genérica que inclui tratamento básico de erros e suporte a tipagem forte:
using System;
using System.Reflection;
namespace UtilitariosReflexao
{
public static class AcessorDinamico
{
public static void AtribuirValor(object alvo, string nomeCampo, object valor)
{
FieldInfo metadado = alvo.GetType().GetField(nomeCampo);
if (metadado == null)
throw new ArgumentNullException(nameof(nomeCampo), "O campo especificado não existe.");
metadado.SetValue(alvo, valor);
}
public static T ObterValor<t>(object alvo, string nomeCampo)
{
FieldInfo metadado = alvo.GetType().GetField(nomeCampo);
if (metadado == null)
throw new ArgumentNullException(nameof(nomeCampo), "O campo especificado não existe.");
return (T)metadado.GetValue(alvo);
}
public static void AtribuirValorGenerico<t>(object alvo, string nomeCampo, T valor)
{
FieldInfo metadado = alvo.GetType().GetField(nomeCampo);
if (metadado == null)
throw new ArgumentNullException(nameof(nomeCampo), "O campo especificado não existe.");
if (metadado.FieldType != typeof(T))
throw new ArgumentException("Tipo incompatível com o campo.");
metadado.SetValue(alvo, valor);
}
}
}</t></t>
Esta classe fornece métodos para atribuição e leitura genérica, com validação adicional para reduzir erros em tempo de execução. O método AtribuirValorGenerico vreifica explicitamente a compatibilidade de tipos antes da operação.