Question

Quelle est exactement la réflexion? Je lis l'article de Wikipedia sur ce sujet et je comprends qu'il est une sorte de méta-programmation, où le programme peut se modifier à l'exécution, mais qu'est-ce que cela veut dire? Dans quel genre de situations est-ce une bonne approche et quand est-il le meilleur pour l'utiliser?

Était-ce utile?

La solution

La réflexion est un établissement où vous pouvez interroger un objet au sujet de ses attributs à l'exécution. Par exemple, Python, Java et .Net ont des installations où vous pouvez trouver les variables d'instance ou les méthodes d'un objet.

Un exemple d'une application pour la réflexion est une couche de mappage O / R. Une réflexion de l'utilisation pour la construction d'un objet par quering ses propriétés lors de l'exécution et de remplir dynamiquement une instance. Cela vous permet de le faire en fonction des métadonnées programatically d'une sorte de dictionnaire de données sans avoir à recompiler l'application.

Pour prendre un exemple simple, je vais utiliser Python parce que ses installations de réflexion sont très simples à utiliser et impliquer moins boilerplate que ceux de Java ou .Net.

ActivePython 2.5.2.2 (ActiveState Software Inc.) based on
Python 2.5.2 (r252:60911, Mar 27 2008, 17:57:18) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> class foo:
...     def __init__(self):
...             self.x = 1
...
>>> xx = foo()      # Creates an object and runs the constructor
>>> xx.__dict__     # System metadata about the object
{'x': 1}
>>> a = xx.__dict__ # Now we manipulate the object through 
>>> a['y'] = 2      # its metadata ...
>>> print xx.y      # ... and suddenly it has a new instance variable
2                   
>>>

Maintenant, nous avons utilisé la réflexion de base pour examiner les variables d'instance d'un objet quelconque. La variable spéciale __dict__ sur python est une propriété de système d'un objet qui a une table de hachage de ses membres à clé par le nom de la variable (ou procédé). Nous avons examiné pensivement l'objet et utilisé les installations de réflexion pour pousser artificiellement une seconde variable d'instance en elle, que l'on peut alors afficher en invoquant comme une variable d'instance.

Notez que cette astuce particulière ne fonctionne pas sur Java ou .Net, comme les variables d'instance sont fixes. Le système de type de ces langues ne permet pas de nouvelles variables d'instance à ajouter lors de l'exécution de la manière que le système de frappe de canard 'python fait. Cependant, vous pourriez avoir pensivement mis à jour la valeur d'une variable d'instance qui a été déclaré dans la définition de type.

Vous pouvez également utiliser la réflexion pour construire dynamiquement des invocations de méthode et effectuer diverses autres astuces intéressantes telles que instanciation d'un objet en fonction d'un paramètre. Par exemple, si vous aviez une sorte de système à base de plug-in où certaines capacités étaient en option, vous pouvez utiliser la réflexion pour interroger le plugin sur les services qu'il offre (peut-être en demandant si certaines interfaces ont été mises en œuvre) sans nécessiter de métadonnées explicites.

De nombreuses interfaces de langage dynamique telles que la réflexion de l'utilisation de l'automatisation OLE comme partie intégrante de l'interface.

Autres conseils

Il est pas tellement modification code au moment de l'exécution, mais l'examen d'objets et de leur demander d'exécuter du code sans connaître leur type statique.

Une façon simple de le décrire serait « une façon un peu douloureux de faire un langage typé statiquement se comportent de façon dynamique. »

EDIT: Usages:

  • Configuration (prendre par exemple un fichier XML qui spécifie les types et les propriétés, puis construire des objets appropriés)
  • Test (tests unitaires qui sont identifiés par leur nom ou attributs)
  • Services Web (.NET au moins, beaucoup de réflexion est utilisé dans le moteur de service Web de base)
  • câblage automatique des événements - fournir une méthode avec un nom approprié, par exemple Et ASP.NET va SubmitButton_Click attacher cette méthode en tant que gestionnaire pour l'événement de SubmitButton du Click (si vous avez autowiring activé)

Est-ce une bonne idée? Eh bien, que lorsque les alternatives sont douloureuses. Je préfère typage statique quand il ne reçoit pas de la manière - alors vous obtenez beaucoup de bonté à la compilation, et il est plus rapide aussi. Mais quand vous Bougez en ont besoin, de réflexion vous permet de faire différentes choses qui, autrement, tout ne serait pas possible.

Le premier exemple que je peux penser à du haut de ma tête lorsque vous devez exécuter un ensemble de méthodes sur un objet donné sans le savoir à la compilation quelles méthodes existeront en elle.

Prenez des frameworks de tests unitaires, par exemple. La classe de coureur de test qui est responsable de l'exécution tous vos tests unitaires ne sait pas à l'avance ce que vous allez nommer vos méthodes. Tout ce qu'il sait est qu'ils seront préfixés par « test » (ou dans le cas de Java 5, annotée avec @Test). Ainsi, lorsque donné une classe de test, il réfléchit sur cette classe afin d'obtenir une liste de toutes les méthodes qu'il contient. , Il itère ensuite à travers les noms de méthode que les chaînes et appelle ces méthodes sur l'objet si elles commencent par « test ». Ce ne serait pas possible sans réflexion. Et c'est un exemple.

La réflexion m'a été utile dans au moins 1 projet, je peux penser. Nous avons écrit un programme « Process Manager » interne qui effectue un grand nombre de processus d'affaires clés à certains intervalles. Le projet est mis en place afin que le noyau est vraiment juste un service de fenêtres avec des objets de minuterie que le feu éteint toutes les 30 secondes environ et vérifier le travail à faire.

Le travail réel est fait dans une bibliothèque de classes (à juste titre appelé « WorkerLib »). Nous définissons les classes avec des méthodes publiques qui effectuent certaines tâches (déplacer des fichiers, téléchargement des données sur des sites distants, etc.) L'idée est que le service de base peut appeler des méthodes de la bibliothèque des travailleurs sans savoir quoi que ce soit au sujet des méthodes qu'il appelle. Cela nous permet de créer un calendrier dans la base de données pour les emplois, et même ajouter de nouvelles méthodes dans la bibliothèque de classes sans avoir à modifier le système de base.

L'idée de base est que nous pouvons utiliser la réflexion au service de base pour exécuter des méthodes dont les noms que nous avons stocké dans la base de données définissant les horaires. Il est assez propre dans la pratique. Notre service de base est solide et gère l'exécution des tâches en fonction des besoins, alors que la bibliothèque des travailleurs réelle peut être étendu et modifié si nécessaire sans le cœur même soin.

Si vous avez besoin d'explications, s'il vous plaît ne hésitez pas à demander. C'était tout simplement la meilleure façon que je pouvais penser à expliquer un scénario réel où la réflexion fait vraiment les choses plus faciles pour nous.

Un autre exemple: j'ai le code que j'utilise qui prend la sortie d'une base de données - qui est un ensemble de lignes avec des colonnes nommées - et des flux dans un tableau d'objets. J'itérer les lignes, et si l'objet cible a une propriété avec le même nom et le type, je l'ai mis. Cela rend mon code d'obtenir des données simplement regarder quelque chose comme ceci:

SqlDataReader sdr = Helper.GetReader("GetClientByID", ClientID);
Client c = new Client();
FillObject(sdr, c);
return c;

Vraiment, la réflexion doit être considéré comme une sorte d'un amplificateur pour le code. Il peut faire du bon code meilleur et plus propre, et pire mauvais code. Qu'est ce que ça fait? Il vous permet vraiment d'écrire du code, que vous n'êtes pas tout à fait certain de ce qu'il va faire au moment où vous écrivez. Vous avez une idée générale, mais il vous permet de coder pas quels objets, méthodes et propriétés allez exécuter lorsque le programme est compilé.

D'autres messages sont corrects quand ils disent qu'il permet au programme d'exécuter du code en fonction des valeurs de configuration, mais il est vrai pouvoir est qu'il vous permet de plier sévèrement les règles de la programmation orientée objet. C'est vraiment ce qu'il fait. Il est un peu comme tourner les mesures de sécurité hors tension. Les méthodes privées et propriétés sont accessibles par la réflexion avec à peu près tout le reste.

Un excellent exemple quand MS utilise la réflexion est avec liaison de données sur l'objet de données. Vous spécifiez le nom du champ texte et champ de données pour un objet de se lier à une liste déroulante, etc., et le code reflète l'objet et tire les informations appropriées. L'objet de liaison de données le même processus encore et encore, mais il ne sait pas quel type d'objet il doit se lier avec. La réflexion est un moyen pratique d'écrire un peu de code pour gérer tous les cas possibles.

En Java, il est essentiellement un moyen d'instancier une classe sans le savoir à ce sujet avant la main. Dites que vous voulez que l'utilisateur de pouvoir modifier un fichier de configuration en ajoutant la classe qu'ils veulent votre programme à utiliser (que vous avez de nombreuses implémentations d'une certaine interface). Avec la réflexion, vous pouvez créer un objet basé sur juste son nom, signature de la méthode, etc.. . puis le jeter à votre interface.

La réflexion est utile pour la configuration d'exécution, ce qui permet des parties d'un système pour être entraînés par la configuration externe.

Par exemple, une usine de classe pourrait construire différents types de béton à base d'un fichier d'entrée, où les types de béton nécessitent différentes informations de configuration pour appeler un constructeur en béton plutôt que d'utiliser une interface constructeur. (La méthode de constructeur de l'objet étant situé réflexion en utilisant).

La réflexion est (essentiellement) la capacité d'un programme à rechercher des informations de type qui était disponible au compilateur. Ainsi, par exemple, étant donné le nom d'un type que vous pouvez interroger les méthodes qu'il contient. Ensuite, pour chaque méthode que vous pouvez interroger les types de paramètres qu'ils prennent etc etc etc.

Il est utile pour la configuration d'exécution où vous avez un fichier de configuration qui spécifie le comportement de votre application. La configuration peut contenir les noms des types concrets que vous devez utiliser (comme cela est souvent le cas avec des conteneurs du CIO). En utilisant la réflexion, vous pouvez créer une instance de ce type de béton (via une API de réflexion) et l'utiliser.

Je vais vous donner un exemple.

Comme un exercice de programmation, j'ai écrit un fichier mp3 vérificateur. Il scanne ma bibliothèque musicale et affiche les balises ID1 / ID2 Je suis intéressé par un DataGridView. J'utilise la réflexion pour obtenir les propriétés de la classe info mp3 sans le code de l'interface utilisateur d'avoir à connaître quoi que ce soit au sujet de cette classe. Si je veux changer les informations que je peux soit affiché obtient modifier la classe info mp3 ou modifier sa configuration (selon la façon dont je l'ai écrit la classe) et ne pas mettre à jour l'interface utilisateur.

Il est également signifiait que je suis en mesure d'utiliser l'injection de dépendance d'utiliser le même d'un bout à afficher des informations sur des photos numériques simplement en échangeant la classe de la bibliothèque de données.

assemblées contiennent les modules, les modules contiennent des types et des types contiennent des membres. La réflexion fournit des objets qui encapsulent des assemblages, des modules et des types. Vous pouvez utiliser la réflexion pour créer dynamiquement une instance d'un type, lier le type à un objet existant, ou obtenir le type d'un objet existant. Vous pouvez ensuite appeler les méthodes du type ou de accéder à ses champs et propriétés. Les utilisations typiques de réflexion sont les suivantes:

  • Utilisez Assemblée pour définir et ensembles de charge, des modules de charge répertoriés dans le manifeste de montage et localisent un type de cet ensemble et créer une instance de celui-ci.
  • Utilisez le module pour découvrir des informations telles que l'assemblage qui contient le module et les classes dans le module. Vous pouvez également obtenir toutes les méthodes globales ou d'autres méthodes spécifiques, définies sur le non globales module.
  • Utilisez ConstructorInfo pour découvrir des informations telles que le nom, les paramètres, les modificateurs d'accès (comme public ou privé), et les détails de mise en œuvre (comme abstraite ou virtuelle) d'un constructeur. Utilisez les GetConstructors ou méthode GetConstructor d'un type d'invoquer un constructeur spécifique.
  • Utilisez MethodInfo pour découvrir des informations telles que le nom, le type de retour, les paramètres, les modificateurs d'accès (comme public ou privé), et les détails de mise en œuvre (comme abstraite ou virtuelle) d'une méthode. Utilisez les GetMethods ou méthode GetMethod d'un type d'invoquer une méthode spécifique.
  • Utilisez FieldInfo pour découvrir des informations telles que le nom, les modificateurs d'accès (tels que publics ou privés) et les détails de mise en œuvre (comme statique) d'un champ et d'obtenir ou de valeurs de champ définies.
  • Utilisez EventInfo pour découvrir des informations telles que le nom, le type de données gestionnaire d'événements, les attributs personnalisés, déclarant type et reflète le type d'un événement, et pour ajouter ou supprimer des gestionnaires d'événements.
  • Utilisez PropertyInfo pour découvrir des informations telles que le nom, le type de données, le type déclarant, le type réfléchi, et en lecture seule ou écriture état d'une propriété, et pour obtenir ou des valeurs de propriété.
  • Utiliser ParameterInfo pour découvrir des informations telles que le nom d'un paramètre, le type de données, si un paramètre est un paramètre d'entrée ou de sortie, et la position du paramètre dans une méthode de signature.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top