Els genèrics són una característica poderosa de C# que permeten definir classes, mètodes i estructures amb un tipus de dades genèric. Això permet que el codi sigui més flexible i reutilitzable, ja que es pot treballar amb diferents tipus de dades sense duplicar el codi.
Conceptes Clau
- Definició de Genèrics: Els genèrics permeten crear classes, mètodes, interfícies i delegats que poden treballar amb qualsevol tipus de dades.
- Paràmetres de Tipus: Els genèrics utilitzen paràmetres de tipus per especificar el tipus de dades amb el qual treballaran.
- Restriccions de Tipus: Es poden aplicar restriccions als paràmetres de tipus per limitar els tipus de dades que es poden utilitzar.
Avantatges dels Genèrics
- Reutilització del Codi: Permeten escriure codi que pot treballar amb qualsevol tipus de dades.
- Seguretat de Tipus: Proporcionen seguretat de tipus en temps de compilació, evitant errors de tipus en temps d'execució.
- Rendiment: Milloren el rendiment en comparació amb l'ús de tipus objecte, ja que eviten la necessitat de conversions de tipus (boxing/unboxing).
Exemples Pràctics
Exemple 1: Classe Genèrica
// Definició d'una classe genèrica
public class Caixa<T>
{
private T contingut;
public void Afegir(T element)
{
contingut = element;
}
public T Obtenir()
{
return contingut;
}
}
// Ús de la classe genèrica
public class Programa
{
public static void Main()
{
Caixa<int> caixaEnter = new Caixa<int>();
caixaEnter.Afegir(123);
Console.WriteLine(caixaEnter.Obtenir()); // Sortida: 123
Caixa<string> caixaString = new Caixa<string>();
caixaString.Afegir("Hola, món!");
Console.WriteLine(caixaString.Obtenir()); // Sortida: Hola, món!
}
}Exemple 2: Mètode Genèric
// Definició d'un mètode genèric
public class Utilitats
{
public static void Intercanviar<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
}
// Ús del mètode genèric
public class Programa
{
public static void Main()
{
int x = 1, y = 2;
Utilitats.Intercanviar(ref x, ref y);
Console.WriteLine($"x: {x}, y: {y}"); // Sortida: x: 2, y: 1
string s1 = "Hola", s2 = "Adéu";
Utilitats.Intercanviar(ref s1, ref s2);
Console.WriteLine($"s1: {s1}, s2: {s2}"); // Sortida: s1: Adéu, s2: Hola
}
}Exemple 3: Restriccions de Tipus
// Definició d'una classe genèrica amb restriccions de tipus
public class Comparador<T> where T : IComparable<T>
{
public T Max(T a, T b)
{
return a.CompareTo(b) > 0 ? a : b;
}
}
// Ús de la classe genèrica amb restriccions de tipus
public class Programa
{
public static void Main()
{
Comparador<int> comparadorEnter = new Comparador<int>();
Console.WriteLine(comparadorEnter.Max(3, 7)); // Sortida: 7
Comparador<string> comparadorString = new Comparador<string>();
Console.WriteLine(comparadorString.Max("poma", "plàtan")); // Sortida: plàtan
}
}Exercicis Pràctics
Exercici 1: Classe Genèrica de Pila
Crea una classe genèrica Pila<T> que implementi les operacions bàsiques d'una pila (push, pop, peek).
Solució
public class Pila<T>
{
private List<T> elements = new List<T>();
public void Push(T element)
{
elements.Add(element);
}
public T Pop()
{
if (elements.Count == 0)
throw new InvalidOperationException("La pila està buida.");
T element = elements[elements.Count - 1];
elements.RemoveAt(elements.Count - 1);
return element;
}
public T Peek()
{
if (elements.Count == 0)
throw new InvalidOperationException("La pila està buida.");
return elements[elements.Count - 1];
}
public int Count => elements.Count;
}
// Ús de la classe genèrica Pila
public class Programa
{
public static void Main()
{
Pila<int> pilaEnter = new Pila<int>();
pilaEnter.Push(1);
pilaEnter.Push(2);
pilaEnter.Push(3);
Console.WriteLine(pilaEnter.Pop()); // Sortida: 3
Console.WriteLine(pilaEnter.Peek()); // Sortida: 2
Console.WriteLine(pilaEnter.Count); // Sortida: 2
}
}Exercici 2: Mètode Genèric de Cerca
Crea un mètode genèric Cerca<T> que busqui un element en una llista i retorni la seva posició.
Solució
public class Utilitats
{
public static int Cerca<T>(List<T> llista, T element)
{
for (int i = 0; i < llista.Count; i++)
{
if (llista[i].Equals(element))
return i;
}
return -1; // Retorna -1 si l'element no es troba
}
}
// Ús del mètode genèric Cerca
public class Programa
{
public static void Main()
{
List<int> llistaEnter = new List<int> { 1, 2, 3, 4, 5 };
Console.WriteLine(Utilitats.Cerca(llistaEnter, 3)); // Sortida: 2
List<string> llistaString = new List<string> { "poma", "plàtan", "taronja" };
Console.WriteLine(Utilitats.Cerca(llistaString, "plàtan")); // Sortida: 1
}
}Resum
En aquesta secció, hem après sobre els genèrics en C#, incloent-hi la seva definició, avantatges i com utilitzar-los en classes i mètodes. També hem vist com aplicar restriccions de tipus per limitar els tipus de dades que es poden utilitzar amb genèrics. Els exercicis pràctics proporcionats ajuden a reforçar aquests conceptes i a veure com es poden aplicar en situacions reals. En la següent secció, explorarem les col·leccions genèriques i com utilitzar-les per gestionar dades de manera eficient.
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ó
