La reflexió és una característica poderosa del llenguatge C# que permet a un programa inspeccionar i manipular la seva pròpia estructura en temps d'execució. Aquesta capacitat és especialment útil per a la creació de biblioteques de classes genèriques, eines de depuració, frameworks de proves i altres aplicacions avançades.

Conceptes Clau

  1. Namespace System.Reflection: Conté les classes i mètodes necessaris per treballar amb la reflexió.
  2. Tipus de Reflexió: Inclou la inspecció de tipus, membres, mètodes, propietats, camps, constructors i esdeveniments.
  3. Creació Dinàmica d'Objectes: Permet crear instàncies de tipus en temps d'execució.
  4. Invocació Dinàmica de Mètodes: Permet invocar mètodes en temps d'execució.

Exemples Pràctics

Inspecció de Tipus

using System;
using System.Reflection;

public class Persona
{
    public string Nom { get; set; }
    public int Edat { get; set; }

    public void Saludar()
    {
        Console.WriteLine("Hola!");
    }
}

class Program
{
    static void Main()
    {
        Type tipus = typeof(Persona);

        // Obtenir informació sobre el tipus
        Console.WriteLine("Nom del Tipus: " + tipus.Name);
        Console.WriteLine("Namespace: " + tipus.Namespace);

        // Obtenir informació sobre les propietats
        PropertyInfo[] propietats = tipus.GetProperties();
        foreach (var prop in propietats)
        {
            Console.WriteLine("Propietat: " + prop.Name + ", Tipus: " + prop.PropertyType);
        }

        // Obtenir informació sobre els mètodes
        MethodInfo[] metodes = tipus.GetMethods();
        foreach (var metode in metodes)
        {
            Console.WriteLine("Mètode: " + metode.Name);
        }
    }
}

Creació Dinàmica d'Objectes

using System;
using System.Reflection;

public class Persona
{
    public string Nom { get; set; }
    public int Edat { get; set; }

    public void Saludar()
    {
        Console.WriteLine("Hola!");
    }
}

class Program
{
    static void Main()
    {
        Type tipus = typeof(Persona);

        // Crear una instància de Persona dinàmicament
        object instancia = Activator.CreateInstance(tipus);

        // Establir valors de propietats dinàmicament
        PropertyInfo propNom = tipus.GetProperty("Nom");
        propNom.SetValue(instancia, "Joan");

        PropertyInfo propEdat = tipus.GetProperty("Edat");
        propEdat.SetValue(instancia, 30);

        // Invocar mètode dinàmicament
        MethodInfo metodeSaludar = tipus.GetMethod("Saludar");
        metodeSaludar.Invoke(instancia, null);

        // Mostrar valors de propietats
        Console.WriteLine("Nom: " + propNom.GetValue(instancia));
        Console.WriteLine("Edat: " + propEdat.GetValue(instancia));
    }
}

Exercicis Pràctics

Exercici 1: Inspecció de Tipus

Descripció: Escriu un programa que inspeccioni un tipus donat i mostri tota la informació sobre els seus camps, propietats, mètodes i constructors.

Solució:

using System;
using System.Reflection;

public class Exemple
{
    public int Camp;
    public string Propietat { get; set; }

    public Exemple() { }
    public Exemple(int valor) { Camp = valor; }

    public void Metode() { }
}

class Program
{
    static void Main()
    {
        Type tipus = typeof(Exemple);

        // Obtenir informació sobre els camps
        FieldInfo[] camps = tipus.GetFields();
        foreach (var camp in camps)
        {
            Console.WriteLine("Camp: " + camp.Name + ", Tipus: " + camp.FieldType);
        }

        // Obtenir informació sobre les propietats
        PropertyInfo[] propietats = tipus.GetProperties();
        foreach (var prop in propietats)
        {
            Console.WriteLine("Propietat: " + prop.Name + ", Tipus: " + prop.PropertyType);
        }

        // Obtenir informació sobre els mètodes
        MethodInfo[] metodes = tipus.GetMethods();
        foreach (var metode in metodes)
        {
            Console.WriteLine("Mètode: " + metode.Name);
        }

        // Obtenir informació sobre els constructors
        ConstructorInfo[] constructors = tipus.GetConstructors();
        foreach (var constructor in constructors)
        {
            Console.WriteLine("Constructor: " + constructor.ToString());
        }
    }
}

Exercici 2: Creació i Invocació Dinàmica

Descripció: Escriu un programa que creï una instància d'una classe dinàmicament, estableixi els valors de les seves propietats i invoqui un dels seus mètodes.

Solució:

using System;
using System.Reflection;

public class Salutacio
{
    public string Missatge { get; set; }

    public void MostrarMissatge()
    {
        Console.WriteLine(Missatge);
    }
}

class Program
{
    static void Main()
    {
        Type tipus = typeof(Salutacio);

        // Crear una instància de Salutacio dinàmicament
        object instancia = Activator.CreateInstance(tipus);

        // Establir valor de la propietat dinàmicament
        PropertyInfo propMissatge = tipus.GetProperty("Missatge");
        propMissatge.SetValue(instancia, "Hola, món!");

        // Invocar mètode dinàmicament
        MethodInfo metodeMostrarMissatge = tipus.GetMethod("MostrarMissatge");
        metodeMostrarMissatge.Invoke(instancia, null);
    }
}

Errors Comuns i Consells

  1. Error: NullReferenceException: Assegura't que el tipus i els membres que estàs intentant accedir existeixen i no són nuls.
  2. Error: TargetInvocationException: Aquest error pot ocórrer quan es produeix una excepció dins del mètode invocat. Revisa el codi del mètode per trobar possibles problemes.
  3. Consell: Utilitza la reflexió amb precaució, ja que pot afectar el rendiment del teu programa. Només utilitza-la quan sigui realment necessari.

Conclusió

La reflexió és una eina poderosa en C# que permet als desenvolupadors inspeccionar i manipular tipus en temps d'execució. Tot i que pot ser complexa i tenir un impacte en el rendiment, és extremadament útil per a una varietat d'aplicacions avançades. Amb la pràctica, podràs utilitzar la reflexió per crear solucions més flexibles i dinàmiques.

© Copyright 2024. Tots els drets reservats