web-dev-qa-db-fra.com

Pourquoi l'utilisation de la réflexion dans .NET est-elle recommandée?

Est-ce vraiment une bonne pratique de l'utiliser?

Quelles sont les situations possibles dans un projet qui nécessitent une réflexion?

56
Jaswant Agarwal

La valeur principale de Reflection est qu'il peut être utilisé pour inspecter des assemblages, des types et des 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 à Reflection indiqueront qu'il est lent, ce qui est vrai par rapport à l'exécution de code statique - cependant Reflection est utilisé dans tout le framework .NET, et à condition qu'il ne soit pas utilisé abusivement, il peut être un outil très puissant dans la boîte à outils.

Quelques applications utiles:

  • Déterminer les dépendances d'un assembly

  • Types d'emplacement qui se conforment à 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 cela peut être un outil pratique dans une reliure.

  • Débogage - vidage d'une liste des assemblys chargés, de leurs références, des méthodes actuelles, etc ...

36
STW

Les usages de la réflexion sont multiples:

  1. Itération des propriétés d'un objet.
  2. Appel d'une méthode définie au moment de l'exécution.
  3. 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 indiquent quelles propriétés de mes classes doivent être indexées à l'aide de Lucene. Au moment de l'exécution, je peux regarder n'importe quelle classe et déterminer quels champs doivent être indexés en interrogeant simplement la classe pour les propriétés "marquées".

31
Esteban Araya

La réflexion n'est qu'un moyen d'investigation des objets pendant l'exécution. Vous ne devriez pas l'utiliser si vous n'en avez pas besoin.

24
Samantha Branham

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 rechercher tous les types dans un assembly et/ou appeler dynamiquement des méthodes dans un assembly.

System.Reflection: l'espace de noms contient les classes et les interfaces qui fournissent une vue gérée des types, méthodes et champs chargés, avec la possibilité de créer et d'invoquer dynamiquement des types; ce processus est connu sous le nom de réflexion dans le cadre .NET.

System.Type: class est la classe principale de la fonctionnalité .NET Reflection et est le principal moyen d'accéder aux métadonnées. La classe System.Type 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érique 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
13
SHEKHAR SHETE

Vous pouvez utiliser la réflexion pour implémenter un système de plugins par exemple. Il vous suffit de rechercher toutes les DLL dans un dossier et de vérifier par réflexion si elles implémentent une certaine interface de plug-in. C'est le but principal pour lequel j'ai utilisé la réflexion, mais je l'ai également utilisée pour implémenter une sérialisation d'objet générique de brassage domestique, où les performances n'étaient pas la plus grande préoccupation.

8
rslite

Comme mentionné ci-dessus, les performances en souffriront.

Un autre grand avantage est que vous pouvez charger dynamiquement des assemblys, effectuer des manipulations de propriétés même si vous n'avez pas la possibilité de voir quoi changer, etc.

Les raisons de l'utiliser sont nombreuses. Voici ne introduction si vous en avez besoin.

6
Kyle Rozendo

La réflexion est couramment utilisée dans les conteneurs IoC. Disons que vous voulez enregistrer chaque classe concrète avec le mot "Controller". La réflexion en fait un morceau de gâteau.

J'ai également utilisé la réflexion pour manipuler des champs privés lors des tests unitaires des classes.

6
Scott Muc

La classe XmlSerialization, très utile, repose sur la réflexion. Vous n'avez pas à gérer vous-même la réflexion pour utiliser la sérialisation, les classes de sérialisation invoquent la réflexion elles-mêmes. Mais cela aide à baliser votre code avec des attributs qui guident la façon dont les objets sont sérialisés. Les classes de sérialisation utilisent la réflexion lors de l'exécution pour lire ces attributs. Au final, le processus semble presque magique, nécessitant très peu de lignes de codage explicites dans une application; c'est la réflexion qui rend cette 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 simple 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.

2
WayneMV

Venant de C++ et ayant eu besoin de 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, au fait?

0
Nick Bedford