D'accord, disons que nous avons une classe définie comme alors nous essayons: p> compilation échoue avec Essayez p> et la compilation échoue à nouveau, avec le même message. p> tout de bien jusqu'à maintenant, nous nous attendions à cela. p> mais on écrit: p> et nous sommes ici, nous a réussi à changer de champ privé. p> n'est-il pas anormal de pouvoir modifier l'état interne de certains objets simplement en utilisant la réflexion? p> EDIT: strong> < / p> Merci pour les réponses jusqu'à présent. Pour ceux qui disent "vous n'avez pas à l'utiliser": Qu'en est-il d'un designer de classe, on dirait qu'il ne puisse plus supposer la sécurité interne de l'état? P> p> TestClass .MyprivateProperty est inaccessible en raison de son niveau de protection de code>, comme prévu. P>
9 Réponses :
réflexion est un outil fort>. Vous mai em> l'utiliser pour casser l'encapsulation, quand il vous en donne plus qu'il enlève. P>
La réflexion a une certaine "douleur" (ou des performances de coût, en lisibilité, dans la fiabilité du code) associée à celle-ci, de sorte que vous ne l'utiliserez pas pour un problème commun. C'est juste plus facile em> de suivre les principes orientés objet des problèmes courants, qui est l'un des objectifs de la langue, communément appelé la fosse du succès . p>
D'autre part, il y a des tâches qui ne seraient pas satisfables sans ce mécanisme, par exemple. Travailler avec des types de génération de temps d'exécution (cependant, cela va être beaucoup plus facile à partir de .NET 4.0 avec son DLR et des variables "dynamiques" en C # 4.0). P>
On peut dire que la réflexion enfreint l'héritage et le polymorphisme. Lorsque au lieu de fournir chaque type d'objet avec sa propre version de méthode surchargée, vous avez une méthode unique qui vérifie le type d'objet au moment de l'exécution et passe à un comportement particulier pour chacun. P>
La réflexion est un bon outil néanmoins. Parfois, vous devez instancier un objet avec un constructeur privé car c'est un plan d'action optimal et vous ne pouvez pas modifier la mise en œuvre de la classe (bibliothèque fermée, vous ne pouvez plus entrer en contact avec l'auteur.). Ou vous souhaitez effectuer une opération auxiliaire sur une variété d'objets au même endroit. Ou peut-être que vous souhaitez effectuer une journalisation pour certains types. Ce sont la situation lorsque la réflexion aide sans causer de mal. P>
Cela fait partie de la fonctionnalité fournie par la réflexion, mais non, je dirais, la meilleure utilisation de celle-ci. p>
Cela ne fonctionne que sous la pleine confiance. P>
Je suppose que vous pourriez dire cela. Vous pouvez également dire que la codification, l'émettant de la réflexion et l'expression de l'arborescence des APIS de l'encapsulation en vous permettant d'écrire du code à la volée. Ce ne sont que des installations fournies par .NET. Vous n'avez pas à les utiliser. P>
N'oubliez pas que vous devez (a) fonctionner en pleine confiance, et (b) spécifier explicitement bindingflags.nonpublic code>, afin d'accéder aux données privées. Cela devrait être suffisant d'un filet de sécurité. P>
Non, ce n'est pas anormal.
C'est quelque chose que la réflexion vous permet de faire, dans une certaine situation, ce que vous avez fait peut être d'une certaine utilisation, dans de nombreux autres que vous ferez simplement votre code une bombe de temps. P>
Réflexion est un outil, il peut être utilisé ou abusé. P>
En ce qui concerne la question après votre édition: la réponse est tout simplement non.
Un designer API pourrait faire de son mieux, mettre beaucoup d'efforts à l'exposition d'une interface propre et à voir son API trop mal utilisé en utilisant la réflexion. P>
Un ingénieur peut modéliser une machine à laver parfaite sécurisée, ne vous choge pas d'électricité et ainsi de suite, mais si vous le brisez avec un marteau jusqu'à ce que vous voyiez les câbles, personne ne va blâmer l'ingénieur si vous obtenez Un choc: D P>
HAHA, machine à laver ... L'encapsulation est donc livrée avec un certificat de garantie, vous dites;)?
Hehehe ... peut-être avec un contrat: p
Le principe d'encapsulation est tiré par votre API, mais la réflexion vous donne un moyen de contourner l'API. P>
Quiconque utilise la réflexion sait qu'il n'utilise pas votre API correctement! P>
Réflexion peut vous aider à garder votre code propre. Par exemple. Lorsque vous utilisez Hibernate, vous pouvez directement lier les variables privées aux valeurs DB et vous n'avez pas à écrire des méthodes de setter inutiles que vous n'auriez pas besoin autrement. Vu de ce point de vue, la réflexion peut vous aider à garder l'encapsulation. P>
Vous avez raison que la réflexion puisse être opposée à n'importe quel nombre de bons principes de conception, mais il peut également s'agir d'un bloc de construction essentiel que vous pouvez utiliser pour soutenir de bons principes de conception - par exemple. Des logiciels pouvant être étendus par des plugins, une inversion de contrôle, etc.
Si vous craignez que cela représente une capacité qui devrait être découragée, vous pouvez avoir un point. Mais ce n'est pas aussi pratique d'utiliser que de vraies caractéristiques linguistiques, il est donc plus facile de faire les choses de la bonne manière. P>
Si vous pensez que la réflexion doit être impossible em>, vous rêvez ! P> en C ++, il n'y a pas de réflexion en tant que tel. Mais il y a un "modèle d'objet" sous-jacent que le code machine généré par le compilateur utilise pour accéder à la structure des objets (et fonctions virtuelles). Donc, un programmeur C ++ peut casser l'encapsulation de la même manière. p> Nous pouvons prendre un pointeur sur un objet de type Tout système restreint doit être mis en œuvre sur un système plus flexible, il est donc toujours possible de le contourner. Si la réflexion n'était pas fournie sous forme de fonctionnalité BCL, une personne pourrait l'ajouter avec une bibliothèque à l'aide de code dangereux. P> Dans certaines langues, il existe des moyens d'encapsuler des données de manière à ce qu'elle ne soit pas possible dans la langue em> pour obtenir aux données sauf de certaines manières prescrites. Mais il sera toujours possible de tricher si vous pouvez trouver un moyen de sortir de la langue. Un exemple extrême serait des variables scopées dans JavaScript: p> après exécution, l'espace de noms global contient deux fonctions, reallclass code> et simplement le jeter à
fakeclass code> et accédez à " Membre privé. p>
myGetter code> et
mysetter < / Code>, qui sont le seul moyen d'accéder à la valeur de
x code>. JavaScript n'a pas de capacité réfléchissante à obtenir au
x code> tout autre moyen. Mais il doit fonctionner dans une sorte d'interprète hôte (par exemple dans le navigateur), et il existe donc un moyen horrible de manipuler
x code>. Un bogue de corruption de mémoire dans un plugin pourrait le faire par accident! P> p>
Réflexion rompt les principes d'encapsulation en donnant accès aux champs et aux méthodes privés, mais ce n'est pas le premier ou unique moyen dans lequel l'encapsulation peut être contournée; On pourrait affirmer que la sérialisation expose toutes les données internes d'une classe, des informations qui seraient normalement privées. P>
Il est important de comprendre que l'encapsulation n'est qu'une technique qui permet de concevoir un comportement plus facile, à condition que les consommateurs acceptent d'utiliser une API que vous avez définie. Si quelqu'un choisit de contourner votre API à l'aide de la réflexion ou de toute autre technique, ils n'ont plus l'assurance que votre objet se comportera comme vous l'avez conçue. Si quelqu'un attribue une valeur de Dans mon expérience, la programmation concerne toutes les assertions et hypothèses. La langue affirme les contraintes (classes, interfaces, énumérations) qui rendent la création d'un comportement isolé beaucoup plus facile à produire, sur l'hypothèse qu'un consommateur accepte de ne pas violer ces frontières. p>
Ceci est une affirmation équitable forte> forte> à faire étant donné qu'elle fait une approche de division et de conquérir du développement logiciel plus facile que toute technique avant elle. P> null code> dans un champ privé, il serait préférable d'être prêt à attraper un
NullReferenceException code> la prochaine fois qu'ils essaient d'utiliser votre classe! P>
Bien que cette question ait reçu d'autres réponses d'excellentes réponses, je chérie en raison de l'accent mis sur le fait qu'il faut considérer l'encapsulation comme une technique (recommandée) parmi d'autres.
Juste en utilisant la réflexion? Quelqu'un n'utilise pas seulement la réflexion, celle sait exactement, qu'il enfreint l'API.