La réflexion en particulier sur les membres privés est fausse
- La réflexion rompt la sécurité du type. Vous pouvez essayer d'invoquer une méthode qui n'existe plus (ou plus), ou avec les mauvais paramètres, ou avec trop de paramètres, ou pas assez ... ou même dans le mauvais ordre (celui-ci mon préféré :)). Par ailleurs, le type de retour pourrait également changer.
- La réflexion est lente.
La réflexion des membres privés rompt le principe d' encapsulation et expose ainsi votre code aux éléments suivants:
- Augmentez la complexité de votre code car il doit gérer le comportement interne des classes. Ce qui est caché doit rester caché.
- Rend votre code facile à casser car il se compilera mais ne s'exécutera pas si la méthode a changé de nom.
- Rend le code privé facile à casser car s'il est privé, il n'est pas destiné à être appelé de cette façon. Peut-être que la méthode privée attend un état intérieur avant d'être appelée.
Et si je dois quand même le faire?
Il y a donc des cas, lorsque vous dépendez d'un tiers ou que vous avez besoin d'une API non exposée, vous devez faire quelques réflexions. Certains l'utilisent également pour tester certaines classes dont ils sont propriétaires mais qui ne veulent pas modifier l'interface pour donner accès aux membres internes uniquement pour les tests.
Si vous le faites, faites-le bien
- Atténuer la facilité de rupture:
Pour atténuer le problème facile à casser, le mieux est de détecter toute rupture potentielle en testant des tests unitaires qui s'exécuteraient dans une version d'intégration continue ou autre. Bien sûr, cela signifie que vous utilisez toujours le même assembly (qui contient les membres privés). Si vous utilisez une charge dynamique et une réflexion, vous aimez jouer avec le feu, mais vous pouvez toujours attraper l'exception que l'appel peut produire.
- Atténuez la lenteur de la réflexion:
Dans les versions récentes de .Net Framework, CreateDelegate battait d'un facteur 50 que MethodInfo invoquait:
// The following should be done once since this does some reflection
var method = this.GetType().GetMethod("Draw_" + itemType,
BindingFlags.NonPublic | BindingFlags.Instance);
// Here we create a Func that targets the instance of type which has the
// Draw_ItemType method
var draw = (Func<TInput, Output[]>)_method.CreateDelegate(
typeof(Func<TInput, TOutput[]>), this);
draw
les appels seront environ 50 fois plus rapides que l' MethodInfo.Invoke
utilisation draw
comme standard Func
comme ça:
var res = draw(methodParams);
Consultez ce post pour voir des références sur différentes invocations de méthodes