Covariance et contravariance (C#)

En C#, la covariance et la contravariance permettent la conversion de références implicite pour les types tableau, les types délégués et les arguments de type générique. La covariance conserve la compatibilité d’assignation et la contravariance l’inverse.

Le code suivant illustre la différence entre la compatibilité d’assignation, la covariance et la contravariance.

// Assignment compatibility.
string str = "test";  
// An object of a more derived type is assigned to an object of a less derived type.
object obj = str;  
  
// Covariance.
IEnumerable<string> strings = new List<string>();  
// An object that is instantiated with a more derived type argument
// is assigned to an object instantiated with a less derived type argument.
// Assignment compatibility is preserved.
IEnumerable<object> objects = strings;  
  
// Contravariance.
// Assume that the following method is in the class:
static void SetObject(object o) { }
Action<object> actObject = SetObject;  
// An object that is instantiated with a less derived type argument
// is assigned to an object instantiated with a more derived type argument.
// Assignment compatibility is reversed.
Action<string> actString = actObject;  

La covariance pour les tableaux permet la conversion implicite d’un tableau d’un type plus dérivé en un tableau d’un type moins dérivé. Cette opération n’est cependant pas sécurisée au niveau des types, comme le montre l’exemple de code suivant.

object[] array = new String[10];  
// The following statement produces a run-time exception.  
// array[0] = 10;  

La prise en charge de la covariance et la contravariance pour les groupes de méthodes permet la correspondance des signatures de méthode avec des types délégués. Ceci vous permet d’affecter aux délégués non seulement les méthodes ayant des signatures correspondantes, mais aussi des méthodes qui retournent des types plus dérivés (covariance) ou qui acceptent des paramètres ayant des types moins dérivés (contravariance) que ceux spécifiés par le type délégué. Pour plus d’informations, consultez Variance dans les délégués (C#) et Utilisation de la variance dans les délégués (C#).

L’exemple de code suivant montre la prise en charge de la covariance et de la contravariance pour les groupes de méthode.

static object GetObject() { return null; }  
static void SetObject(object obj) { }  
  
static string GetString() { return ""; }  
static void SetString(string str) { }  
  
static void Test()  
{  
    // Covariance. A delegate specifies a return type as object,  
    // but you can assign a method that returns a string.  
    Func<object> del = GetString;  
  
    // Contravariance. A delegate specifies a parameter type as string,  
    // but you can assign a method that takes an object.  
    Action<string> del2 = SetObject;  
}  

Dans le NET Framework 4 ou les versions ultérieures, C# prend en charge la covariance et la contravariance dans les interfaces et les délégués génériques, et permet la conversion implicite de paramètres de type générique. Pour plus d’informations, consultez Variance dans les interfaces génériques (C#) et Variance dans les délégués (C#).

L’exemple de code suivant illustre la conversion de références implicite pour les interfaces génériques.

IEnumerable<String> strings = new List<String>();  
IEnumerable<Object> objects = strings;  

Une interface ou un délégué générique est dit de type variant si ses paramètres génériques sont déclarés covariants ou contravariants. C# vous permet de créer vos propres interfaces et délégués de type variant. Pour plus d’informations, consultez Création d’interfaces génériques de type variant (C#) et Variance dans les délégués (C#).

Titre Description
Variance dans les interfaces génériques (C#) Décrit la covariance et la contravariance dans les interfaces génériques et fournit la liste des interfaces génériques de type variant dans .NET.
Création d’interfaces génériques de type variant (C#) Montre comment créer des interfaces de type variant personnalisées.
Utilisation de la variance dans les interfaces pour les collections génériques (C#) Montre comment la prise en charge de la covariance et de la contravariance dans les interfaces IEnumerable<T> et IComparable<T> peut vous aider à réutiliser du code.
Variance dans les délégués (C#) Présente la covariance et la contravariance dans les délégués génériques et non génériques, et fournit une liste des délégués génériques de type variant dans .NET.
Utilisation de la variance dans les délégués (C#) Montre comment utiliser la prise en charge de la covariance et de la contravariance dans les délégués non génériques pour faire correspondre des signatures de méthode avec des types délégués.
Utilisation de la variance pour les délégués génériques Func et Action (C#) Montre comment la prise en charge de la covariance et de la contravariance dans les délégués Func et Action peut vous aider à réutiliser du code.