Pourquoi l'utilisation de la réflexion in.NET recommandé?
Est-ce vraiment une bonne pratique de l'utiliser?
Quelles sont les situations possibles dans un projet qui nécessitent une réflexion?
9 réponses
La valeur principale de Reflection est qu'elle peut être utilisée pour inspecter les assemblys, les types et les membres. C'est un outil très puissant pour déterminer le contenu d'un assemblage ou d'un objet inconnu et peut être utilisé dans une grande variété de cas.
Les opposants à la réflexion citeront qu'elle est lente, ce qui est vrai par rapport à l'exécution de code statique-cependant la réflexion est utilisée dans tout le. Net framework, et à condition qu'elle ne soit pas abusée, elle peut être un outil très puissant dans le Toolkit.
Quelques applications utiles:
Déterminer les dépendances d'un assemblage
-
Les types D'emplacement qui sont conformes à une interface, dérivent d'une classe de base / abstraite et recherchent des membres par attributs
(Smelly) testing - si vous dépendez d'une classe qui n'est pas testable (c'est-à-dire qu'elle ne vous permet pas de construire facilement un faux), vous pouvez utiliser Reflection pour injecter de fausses valeurs dans la classe-ce n'est pas joli, et non recommandé, mais il peut être un outil pratique dans une liaison.
Débogage-vidage d'une liste des assemblys chargés, de leurs références, des méthodes actuelles, etc...
Il y a beaucoup d'utilisations pour la réflexion:
- itération des propriétés dans un objet.
- appeler une méthode définie lors de l'exécution.
- Beaucoup d'autres sur la même veine.
Cependant, l'une de mes utilisations préférées de la réflexion est de trouver des propriétés qui ont été marquées avec des attributs.
Par exemple, j'ai écrit des attributs qui marquent les propriétés de mes classes qui doivent être indexées en utilisant Lucene. Au moment de l'exécution, je peux regarder n'importe quelle classe, et la figure out quels champs doivent être indexés en interrogeant simplement la classe pour les propriétés "marquées".
La réflexion est juste un moyen d'étudier les objets pendant l'exécution. Vous ne devriez pas l'utiliser si vous n'avez pas besoin de le faire.
Reflection permet à une application de collecter des informations sur elle-même et aussi de manipuler sur elle-même. Il peut être utilisé pour trouver tous les types dans un assembly et / ou appeler dynamiquement des méthodes dans un assembly.
Système.Reflection: namespace contient les classes et les interfaces qui fournissent une vue gérée des types, des méthodes et des champs chargés, avec la possibilité de créer et d'invoquer dynamiquement des types; ce processus est connu sous le nom de Reflection dans. NET Framework.
Système.Type: classe est la classe principale pour la fonctionnalité de réflexion. net et est le principal moyen d'accéder aux métadonnées. système.Type class est une classe abstraite et représente un type dans le Common Type System (CLS).
Il représente les déclarations de type: types de classe, types d'interface, types de tableau, types de valeur, types d'énumération, paramètres de type, définitions de type génériques et types génériques construits ouverts ou fermés.
Par exemple:
using System;
using System.Reflection;
static class ReflectionTest
{
public static int Height;
public static int Width;
public static int Weight;
public static string Name;
public static void Write()
{
Type type = typeof(ReflectionTest); // Get type pointer
FieldInfo[] fields = type.GetFields(); // Obtain all fields
foreach (var field in fields) // Loop through fields
{
string name = field.Name; // Get string name
object temp = field.GetValue(null); // Get value
if (temp is int) // See if it is an integer.
{
int value = (int)temp;
Console.Write(name);
Console.Write(" (int) = ");
Console.WriteLine(value);
}
else if (temp is string) // See if it is a string.
{
string value = temp as string;
Console.Write(name);
Console.Write(" (string) = ");
Console.WriteLine(value);
}
}
}
}
class Program
{
static void Main()
{
ReflectionTest.Height = 100; // Set value
ReflectionTest.Width = 50; // Set value
ReflectionTest.Weight = 300; // Set value
ReflectionTest.Name = "ShekharShete"; // Set value
ReflectionTest.Write(); // Invoke reflection methods
}
}
Output
Height (int) = 100
Width (int) = 50
Weight (int) = 300
Name (string) = ShekharShete
Vous pouvez utiliser reflection pour implémenter un système de plugins par exemple. Vous recherchez simplement toutes les DLL dans un dossier et, par réflexion, vérifiez si elles implémentent une certaine interface de plugin. C'est le but principal pour lequel j'ai utilisé la réflexion, mais je l'ai également utilisé pour implémenter une sérialisation d'objet générique home-brew, où la performance n'était pas la plus grande préoccupation.
Comme mentionné ci-dessus, la performance prendra un coup.
Un autre grand avantage est que vous pouvez charger dynamiquement des assemblages, effectuer une manipulation de propriété même si vous n'avez pas la portée de voir quoi changer, etc.
Les raisons d'utiliser ceci sont nombreuses. Voici une introduction si vous avez besoin d'.
La réflexion est couramment utilisée dans les conteneurs IoC. Disons que vous souhaitez enregistrer chaque classe concrète les extrémités avec le mot "Contrôleur". La réflexion en fait un morceau de gâteau.
J'ai également utilisé la réflexion pour manipuler les champs privés lors du test unitaire des classes.
La classe xmlserialization très utile repose sur la réflexion. Vous n'avez pas à traiter la réflexion vous-même pour utiliser la sérialisation, les classes de sérialisation invoquent la réflexion elles-mêmes. Mais cela aide à marquer votre code avec des attributs qui guident la sérialisation des objets. Les classes de sérialisation utilisent la réflexion à l'exécution pour lire ces attributs. En fin de compte, le processus semble presque magique, nécessitant très peu de lignes de codage explicite dans une application; c'est la réflexion qui fait cela commodité possible.
XmlSerialization lui-même est génial non seulement parce que c'est un moyen très pratique de créer des fichiers de données à partir d'une application, c'est aussi un moyen très facile de générer des enregistrements lisibles par l'homme du modèle de données interne d'un programme à des fins de débogage.
Venant de C++ et ayant besoin de quelques hiérarchies de classes simples, je peux dire que le mot clé is
est inestimable!
class MenuItem : Item { }
foreach(Item items in parent.ChildItems) {
if (item is MenuItem) { /* handle differently */ }
}
P.S. la réflexion n'est-elle pas un peu chère, btw?