C # - Génériques

Genericsvous permettent de définir la spécification du type de données des éléments de programmation dans une classe ou une méthode, jusqu'à ce qu'il soit réellement utilisé dans le programme. En d'autres termes, les génériques vous permettent d'écrire une classe ou une méthode qui peut fonctionner avec n'importe quel type de données.

Vous écrivez les spécifications de la classe ou de la méthode, avec des paramètres de substitution pour les types de données. Lorsque le compilateur rencontre un constructeur pour la classe ou un appel de fonction pour la méthode, il génère du code pour gérer le type de données spécifique. Un exemple simple aiderait à comprendre le concept -

using System;
using System.Collections.Generic;

namespace GenericApplication {
   public class MyGenericArray<T> {
      private T[] array;
      
      public MyGenericArray(int size) {
         array = new T[size + 1];
      }
      public T getItem(int index) {
         return array[index];
      }
      public void setItem(int index, T value) {
         array[index] = value;
      }
   }
   class Tester {
      static void Main(string[] args) {
         
         //declaring an int array
         MyGenericArray<int> intArray = new MyGenericArray<int>(5);
         
         //setting values
         for (int c = 0; c < 5; c++) {
            intArray.setItem(c, c*5);
         }
         
         //retrieving the values
         for (int c = 0; c < 5; c++) {
            Console.Write(intArray.getItem(c) + " ");
         }
         
         Console.WriteLine();
         
         //declaring a character array
         MyGenericArray<char> charArray = new MyGenericArray<char>(5);
         
         //setting values
         for (int c = 0; c < 5; c++) {
            charArray.setItem(c, (char)(c+97));
         }
         
         //retrieving the values
         for (int c = 0; c< 5; c++) {
            Console.Write(charArray.getItem(c) + " ");
         }
         Console.WriteLine();
         
         Console.ReadKey();
      }
   }
}

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

0 5 10 15 20
a b c d e

Caractéristiques des génériques

Les génériques sont une technique qui enrichit vos programmes des manières suivantes -

  • Il vous aide à optimiser la réutilisation du code, la sécurité des types et les performances.

  • Vous pouvez créer des classes de collection génériques. La bibliothèque de classes .NET Framework contient plusieurs nouvelles classes de collection génériques dans l' espace de noms System.Collections.Generic . Vous pouvez utiliser ces classes de collection génériques au lieu des classes de collection dans l' espace de noms System.Collections .

  • Vous pouvez créer vos propres interfaces, classes, méthodes, événements et délégués génériques.

  • Vous pouvez créer des classes génériques contraintes pour permettre l'accès aux méthodes sur des types de données particuliers.

  • Vous pouvez obtenir des informations sur les types utilisés dans un type de données générique au moment de l'exécution par réflexion.

Méthodes génériques

Dans l'exemple précédent, nous avons utilisé une classe générique; nous pouvons déclarer une méthode générique avec un paramètre de type. Le programme suivant illustre le concept -

using System;
using System.Collections.Generic;

namespace GenericMethodAppl {
   class Program {
      static void Swap<T>(ref T lhs, ref T rhs) {
         T temp;
         temp = lhs;
         lhs = rhs;
         rhs = temp;
      }
      static void Main(string[] args) {
         int a, b;
         char c, d;
         a = 10;
         b = 20;
         c = 'I';
         d = 'V';
         
         //display values before swap:
         Console.WriteLine("Int values before calling swap:");
         Console.WriteLine("a = {0}, b = {1}", a, b);
         Console.WriteLine("Char values before calling swap:");
         Console.WriteLine("c = {0}, d = {1}", c, d);
         
         //call swap
         Swap<int>(ref a, ref b);
         Swap<char>(ref c, ref d);
         
         //display values after swap:
         Console.WriteLine("Int values after calling swap:");
         Console.WriteLine("a = {0}, b = {1}", a, b);
         Console.WriteLine("Char values after calling swap:");
         Console.WriteLine("c = {0}, d = {1}", c, d);
         
         Console.ReadKey();
      }
   }
}

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

Int values before calling swap:
a = 10, b = 20
Char values before calling swap:
c = I, d = V
Int values after calling swap:
a = 20, b = 10
Char values after calling swap:
c = V, d = I

Délégués génériques

Vous pouvez définir un délégué générique avec des paramètres de type. Par exemple -

delegate T NumberChanger<T>(T n);

L'exemple suivant montre l'utilisation de ce délégué -

using System;
using System.Collections.Generic;

delegate T NumberChanger<T>(T n);
namespace GenericDelegateAppl {
   class TestDelegate {
      static int num = 10;
      
      public static int AddNum(int p) {
         num += p;
         return num;
      }
      public static int MultNum(int q) {
         num *= q;
         return num;
      }
      public static int getNum() {
         return num;
      }
      static void Main(string[] args) {
         //create delegate instances
         NumberChanger<int> nc1 = new NumberChanger<int>(AddNum);
         NumberChanger<int> nc2 = new NumberChanger<int>(MultNum);
         
         //calling the methods using the delegate objects
         nc1(25);
         Console.WriteLine("Value of Num: {0}", getNum());
         
         nc2(5);
         Console.WriteLine("Value of Num: {0}", getNum());
         Console.ReadKey();
      }
   }
}

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

Value of Num: 35
Value of Num: 175