Não é trapaça, mas, como qualquer ferramenta, deve ser usada para o que se destina a resolver. Reflexão, por definição, permite que você inspecione e modifique o código através do código; se é isso que você precisa fazer, a reflexão é a ferramenta para o trabalho. Reflexão é tudo sobre meta-código: código que segmenta código (em oposição ao código regular, que segmenta dados).
Um exemplo de bom uso de reflexão são as classes genéricas da interface de serviço da web: Um design típico é separar a implementação do protocolo da funcionalidade da carga útil. Então você tem uma classe (vamos chamá-la T
) que implementa sua carga útil e outra que implementa o protocolo ( P
). T
é bastante direto: para cada chamada que você deseja fazer, basta escrever um método que faça o que deve ser feito. P
, no entanto, precisa mapear chamadas de serviço da web para chamadas de método. Tornar esse mapeamento genérico é desejável, pois evita redundância e torna P
altamente reutilizável. O Reflection fornece os meios para inspecionar a classe T
em tempo de execução e chamar seus métodos com base nas seqüências de caracteres transmitidas P
pelo protocolo de serviço da web, sem nenhum conhecimento da classe em tempo de compilaçãoT
. Usando a regra 'código sobre código', pode-se argumentar que a classe P
possui o código na classe T
como parte de seus dados.
Contudo.
O Reflection também oferece ferramentas para contornar as restrições do sistema de tipos da linguagem - teoricamente, você pode passar todos os parâmetros como tipo object
e chamar seus métodos através de reflexões. Voilà, a linguagem que deveria impor uma forte disciplina estática de digitação agora se comporta como uma linguagem dinamicamente digitada com ligação tardia, apenas que a sintaxe é muito mais elaborada. Todas as instâncias desse padrão que eu vi até agora foram um hack sujo e, invariavelmente, uma solução dentro do sistema de tipos da linguagem seria possível e seria mais segura, elegante e eficiente em todos os aspectos .
Existem algumas exceções, como controles da GUI que podem ser vinculados a dados para vários tipos não relacionados de fontes de dados; determinar que seus dados implementem uma determinada interface apenas para que você possa vinculá-los a dados não é realista e o programador não deve implementar um adaptador para cada tipo de fonte de dados. Nesse caso, usar a reflexão para detectar o tipo de fonte de dados e ajustar a ligação de dados é uma opção mais útil.