Maîtriser la réflexion en C# : découverte de types à l'exécution et programmation dynamique
La réflexion (System.Reflection) permet d'obtenir des informations de type à l'exécution. Les classes d'accès aux métadonnées d'un programme en cours sont dans System.Reflection.
Applications de la réflexion
- Voir informations d'attributs à l'exécution
- Examiner types dans un assembly et les instancier
- Liaison tardive (late binding) à méthodes/propriétés
- Créer nouveaux types à l'exécution et les utiliser
Visualisation des métadonnées
L'objet MemberInfo doit être initialisé pour découvrir les attributs d'une classe :
System.Reflection.MemberInfo info = typeof(MaClasse);
Exemple : lecture attributs personnalisés
using System;
using System.Reflection;
namespace ApplicationReflexion
{
[AttributeUsage(AttributeTargets.All)]
public class AttributAide : System.Attribute
{
public readonly string Url;
public string Sujet { get; set; }
public AttributAide(string url) { this.Url = url; }
}
[AttributAide("Information sur la classe MaClasse")]
class MaClasse { }
class Programme
{
static void Main(string[] args)
{
MemberInfo info = typeof(MaClasse);
object[] attributs = info.GetCustomAttributes(true);
for (int i = 0; i < attributs.Length; i++)
Console.WriteLine(attributs[i]);
Console.ReadKey();
}
}
}
Résultat : AttributAide
Exemple complet : lecture attributs InfoDebug sur classe Rectangle
using System;
using System.Reflection;
namespace ApplicationCorrectionBugs
{
// Attribut personnalisé (défini chapitre précédent)
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
public class InfoDebug : System.Attribute
{
private int numeroBug;
private string developpeur;
private string derniereRevue;
public string message;
public InfoDebug(int bg, string dev, string d)
{
numeroBug = bg; developpeur = dev; derniereRevue = d;
}
public int NumeroBug { get { return numeroBug; } }
public string Developpeur { get { return developpeur; } }
public string DerniereRevue { get { return derniereRevue; } }
public string Message { get { return message; } set { message = value; } }
}
[InfoDebug(45, "Zara Ali", "12/08/2012", Message = "Type retour incorrect")]
[InfoDebug(49, "Nuha Ali", "10/10/2012", Message = "Variable inutilisée")]
class Rectangle
{
protected double longueur, largeur;
public Rectangle(double l, double w) { longueur = l; largeur = w; }
[InfoDebug(55, "Zara Ali", "19/10/2012", Message = "Type retour incorrect")]
public double ObtenirAire() { return longueur * largeur; }
[InfoDebug(56, "Zara Ali", "19/10/2012")]
public void Afficher()
{
Console.WriteLine("Longueur : {0}", longueur);
Console.WriteLine("Largeur : {0}", largeur);
Console.WriteLine("Aire : {0}", ObtenirAire());
}
}
class ExecuterRectangle
{
static void Main(string[] args)
{
Rectangle r = new Rectangle(4.5, 7.5);
r.Afficher();
Type type = typeof(Rectangle);
// Attributs de classe
foreach (Object attr in type.GetCustomAttributes(false))
{
InfoDebug dbg = attr as InfoDebug;
if (dbg != null)
{
Console.WriteLine("Bug N°: {0}", dbg.NumeroBug);
Console.WriteLine("Développeur: {0}", dbg.Developpeur);
Console.WriteLine("Revue: {0}", dbg.DerniereRevue);
Console.WriteLine("Remarques: {0}", dbg.Message);
}
}
// Attributs de méthodes
foreach (MethodInfo m in type.GetMethods())
{
foreach (Attribute a in m.GetCustomAttributes(true))
{
InfoDebug dbg = a as InfoDebug;
if (dbg != null)
{
Console.WriteLine("Bug N°: {0}, Méthode: {1}", dbg.NumeroBug, m.Name);
Console.WriteLine("Développeur: {0}", dbg.Developpeur);
Console.WriteLine("Revue: {0}", dbg.DerniereRevue);
Console.WriteLine("Remarques: {0}", dbg.Message);
}
}
}
Console.ReadLine();
}
}
}
Résultat :
Longueur: 4.5
Largeur: 7.5
Aire: 33.75
Bug N°: 49
Développeur: Nuha Ali
Revue: 10/10/2012
Remarques: Variable inutilisée
Bug N°: 45
Développeur: Zara Ali
Revue: 12/08/2012
Remarques: Type retour incorrect
Bug N°: 55, Méthode: ObtenirAire
Développeur: Zara Ali
Revue: 19/10/2012
Remarques: Type retour incorrect
Bug N°: 56, Méthode: Afficher
Développeur: Zara Ali
Revue: 19/10/2012
Remarques:
Langue C
- C# Hello World — Construire votre première application C#
- Comprendre les mots-clés et identificateurs C# : règles, listes et bonnes pratiques
- Maîtriser les variables C# et types de données primitifs : guide complet
- Opérateurs C# — Guide complet des opérateurs en C#
- Maîtriser les opérateurs bit à bit et de décalage en C# : Guide complet
- Fondamentaux C# : Entrées et sorties essentielles
- Expressions, instructions et blocs C# : Guide complet avec exemples pratiques
- Maîtriser les commentaires C# : Types, bonnes pratiques et documentation XML
- Instruction Break C# : Comment et quand l'utiliser