11
votes

Reflète-t-il le principe d'encapsulation?

D'accord, disons que nous avons une classe définie comme xxx

alors nous essayons: xxx

compilation échoue avec TestClass .MyprivateProperty est inaccessible en raison de son niveau de protection , comme prévu.

Essayez xxx

et la compilation échoue à nouveau, avec le même message.

tout de bien jusqu'à maintenant, nous nous attendions à cela.

mais on écrit: xxx

et nous sommes ici, nous a réussi à changer de champ privé.

n'est-il pas anormal de pouvoir modifier l'état interne de certains objets simplement en utilisant la réflexion?

EDIT: < / 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?


1 commentaires

Juste en utilisant la réflexion? Quelqu'un n'utilise pas seulement la réflexion, celle sait exactement, qu'il enfreint l'API.


9 Réponses :


9
votes

réflexion est un outil . Vous mai l'utiliser pour casser l'encapsulation, quand il vous en donne plus qu'il enlève.

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 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 .

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).


0 commentaires

2
votes

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.

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.


0 commentaires

2
votes

Cela fait partie de la fonctionnalité fournie par la réflexion, mais non, je dirais, la meilleure utilisation de celle-ci.

Cela ne fonctionne que sous la pleine confiance.


0 commentaires

3
votes

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.

N'oubliez pas que vous devez (a) fonctionner en pleine confiance, et (b) spécifier explicitement bindingflags.nonpublic , afin d'accéder aux données privées. Cela devrait être suffisant d'un filet de sécurité.


0 commentaires

2
votes

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.

Réflexion est un outil, il peut être utilisé ou abusé.


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.

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


2 commentaires

HAHA, machine à laver ... L'encapsulation est donc livrée avec un certificat de garantie, vous dites;)?


Hehehe ... peut-être avec un contrat: p



2
votes

Le principe d'encapsulation est tiré par votre API, mais la réflexion vous donne un moyen de contourner l'API.

Quiconque utilise la réflexion sait qu'il n'utilise pas votre API correctement!


0 commentaires

1
votes

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.


0 commentaires

4
votes

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.

Si vous pensez que la réflexion doit être impossible , vous rêvez !

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. xxx

Nous pouvons prendre un pointeur sur un objet de type reallclass et simplement le jeter à fakeclass et accédez à " Membre privé.

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.

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 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: xxx

après exécution, l'espace de noms global contient deux fonctions, myGetter et mysetter < / Code>, qui sont le seul moyen d'accéder à la valeur de x . JavaScript n'a pas de capacité réfléchissante à obtenir au x 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 . Un bogue de corruption de mémoire dans un plugin pourrait le faire par accident!


0 commentaires

15
votes

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.

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 null dans un champ privé, il serait préférable d'être prêt à attraper un NullReferenceException la prochaine fois qu'ils essaient d'utiliser votre classe!

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.

Ceci est une affirmation équitable à 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.


1 commentaires

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.