Non è un imbroglio, ma come qualsiasi strumento, dovrebbe essere usato per ciò che è destinato a risolvere. Reflection, per definizione, consente di ispezionare e modificare il codice attraverso il codice; se questo è ciò che devi fare, allora la riflessione è lo strumento per il lavoro. La riflessione riguarda tutto il meta-codice: codice che ha come target il codice (al contrario del codice normale, che ha come target i dati).
Un esempio di buon uso della riflessione sono le classi di interfaccia del servizio Web generico: un progetto tipico è quello di separare l'implementazione del protocollo dalla funzionalità di payload. Quindi hai una classe (chiamiamola T
) che implementa il tuo payload e un'altra che implementa il protocollo ( P
). T
è abbastanza semplice: per ogni chiamata che si desidera effettuare, è sufficiente scrivere un metodo che fa tutto ciò che dovrebbe fare. P
, tuttavia, deve mappare le chiamate dei servizi Web alle chiamate di metodo. Rendere questa mappatura generica è desiderabile, perché evita la ridondanza e rende P
altamente riutilizzabile. Reflection fornisce i mezzi per ispezionare la classe T
in fase di runtime e chiamare i suoi metodi in base alle stringhe passate P
attraverso il protocollo del servizio Web, senza alcuna conoscenza della classe in fase di compilazioneT
. Usando la regola 'code about code', si può sostenere che la classe P
ha il codice in classe T
come parte dei suoi dati.
Però.
Reflection ti offre anche strumenti per aggirare le restrizioni del sistema di tipi di linguaggio - teoricamente, potresti passare tutti i parametri come tipo object
e chiamare i loro metodi attraverso le riflessioni. Voilà, il linguaggio che dovrebbe imporre una forte disciplina della tipizzazione statica ora si comporta come un linguaggio tipizzato dinamicamente con associazione tardiva, solo che la sintassi è molto più elaborata. Ogni singola istanza di tale schema che ho visto finora è stata un trucco sporco e, inevitabilmente, una soluzione all'interno del sistema di tipi di linguaggio sarebbe stata possibile, e sarebbe stata più sicura, più elegante e più efficiente sotto tutti gli aspetti .
Esistono alcune eccezioni, come i controlli della GUI che possono essere associati a vari tipi di origini dati non correlate; imporre che i tuoi dati implementino una determinata interfaccia solo in modo che tu possa legarli non è realistico, e nemmeno il programmatore deve implementare un adattatore per ogni tipo di origine dati. In questo caso, utilizzare la riflessione per rilevare il tipo di origine dati e regolare l'associazione dei dati è una scelta più utile.