Méthodes génériques (guide de programmation C#)

Une méthode générique est une méthode qui est déclarée avec des paramètres de type, comme suit :

static void Swap<T>(ref T lhs, ref T rhs)
{
    T temp;
    temp = lhs;
    lhs = rhs;
    rhs = temp;
}

L’exemple de code suivant montre une manière d’appeler la méthode, avec int comme argument de type :

public static void TestSwap()
{
    int a = 1;
    int b = 2;

    Swap<int>(ref a, ref b);
    System.Console.WriteLine(a + " " + b);
}

Vous pouvez également omettre l’argument de type et le compilateur le déduira. L’appel suivant à Swap est équivalent à l’appel précédent :

Swap(ref a, ref b);

Les mêmes règles d’inférence de type s’appliquent aux méthodes statiques et aux méthodes d’instance. Le compilateur peut déduire les paramètres de type d’après les arguments de méthode que vous passez. Il ne peut pas déduire les paramètres de type uniquement à partir d’une valeur de contrainte ou de retour. Par conséquent, l’inférence de type ne fonctionne pas avec les méthodes qui n’ont pas de paramètres. L’inférence de type se produit au moment de la compilation avant que le compilateur n’essaie de résoudre toute signature de méthode surchargée. Le compilateur applique la logique d’inférence de type à toutes les méthodes génériques qui partagent le même nom. À l’étape de résolution de la surcharge, le compilateur inclut uniquement les méthodes génériques sur lesquelles l’inférence de type a réussi.

Dans une classe générique, les méthodes non génériques peuvent accéder aux paramètres de type de niveau classe, comme suit :

class SampleClass<T>
{
    void Swap(ref T lhs, ref T rhs) { }
}

Si vous définissez une méthode générique qui accepte les mêmes paramètres de type que la classe conteneur, le compilateur génère l’avertissement CS0693, car l’argument fourni à l’intérieur de la portée de la méthode pour le T interne masque l’argument fourni pour le T externe. Si vous avez éventuellement besoin d’appeler une méthode de classe générique avec des arguments de type différents de ceux qui ont été fournis quand la classe a été instanciée, envisagez de fournir un autre identificateur pour le paramètre de type de la méthode, comme indiqué dans GenericList2<T> dans l’exemple suivant.

class GenericList<T>
{
    // CS0693.
    void SampleMethod<T>() { }
}

class GenericList2<T>
{
    // No warning.
    void SampleMethod<U>() { }
}

Utilisez des contraintes pour permettre des opérations plus spécialisées sur les paramètres de type dans les méthodes. Cette version de Swap<T>, maintenant appelée SwapIfGreater<T>, peut être utilisée avec des arguments de type qui implémentent IComparable<T> uniquement.

void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
{
    T temp;
    if (lhs.CompareTo(rhs) > 0)
    {
        temp = lhs;
        lhs = rhs;
        rhs = temp;
    }
}

Les méthodes génériques peuvent être surchargées sur plusieurs paramètres de type. Par exemple, les méthodes suivantes peuvent toutes être dans la même classe :

void DoWork() { }
void DoWork<T>() { }
void DoWork<T, U>() { }

Vous pouvez également utiliser le paramètre type comme type de retour d’une méthode. L’exemple de code suivant montre une méthode qui renvoie un tableau de type T :

T[] Swap<T>(T a, T b)
{
    return [b, a];
}

Spécification du langage C#

Pour plus d'informations, voir la spécification du langage C#.

Voir aussi