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
- Namespace
System.Reflection: Conté les classes i mètodes necessaris per treballar amb la reflexió. - Tipus de Reflexió: Inclou la inspecció de tipus, membres, mètodes, propietats, camps, constructors i esdeveniments.
- Creació Dinàmica d'Objectes: Permet crear instàncies de tipus en temps d'execució.
- 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
- Error:
NullReferenceException: Assegura't que el tipus i els membres que estàs intentant accedir existeixen i no són nuls. - 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. - 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.
Curs de Programació en C#
Mòdul 1: Introducció al C#
- Introducció al C#
- Configuració de l'Entorn de Desenvolupament
- Programa Hello World
- Sintaxi i Estructura Bàsica
- Variables i Tipus de Dades
Mòdul 2: Estructures de Control
Mòdul 3: Programació Orientada a Objectes
Mòdul 4: Conceptes Avançats de C#
- Interfícies
- Delegats i Esdeveniments
- Genèrics
- Col·leccions
- LINQ (Consulta Integrada al Llenguatge)
- Programació Asíncrona
Mòdul 5: Treballant amb Dades
Mòdul 6: Temes Avançats
- Reflexió
- Atributs
- Programació Dinàmica
- Gestió de Memòria i Recollida d'Escombraries
- Multifil i Programació Paral·lela
Mòdul 7: Construcció d'Aplicacions
Mòdul 8: Millors Pràctiques i Patrons de Disseny
- Estàndards de Codificació i Millors Pràctiques
- Patrons de Disseny
- Proves Unitàries
- Revisió de Codi i Refactorització
