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ó