Covariance et contravariance (C# et Visual Basic)

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

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

' Assignment compatibility.  
Dim str As String = "test" 
' An object of a more derived type is assigned to an object of a less derived type.  
Dim obj As Object = str

' Covariance.  
Dim strings As IEnumerable(Of String) = New List(Of 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.  
Dim objects As IEnumerable(Of Object) = strings

' Contravariance.            
' Assume that there is the following method in the class:  
' Shared Sub SetObject(ByVal o As Object) 
' End Sub 
Dim actObject As Action(Of Object) = AddressOf 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.  
Dim actString As Action(Of String) = actObject
// 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 des tableaux permet la conversion implicite d'un tableau d'un type plus dérivé en tableau d'un type moins dérivé. Mais ces opérations ne sont pas sécurisées, comme l'illustre l'exemple de code suivant.

Dim array() As Object = New String(10) {}
' The following statement produces a run-time exception. 
' array(0) = 10
object[] array = new String[10];
// The following statement produces a run-time exception. 
// array[0] = 10;

La prise en charge de la covariance et de la contravariance des groupes de méthode permet d'établir une correspondance entre les signatures de méthode et les types délégués. Cela vous permet d'assigner aux délégués pas uniquement les méthodes ayant des signatures correspondantes, mais également 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 Visual Basic) et Utilisation de la variance dans les délégués (C# et Visual Basic).

L'exemple de code suivant indique la prise en charge de la covariance et de la contravariance des groupes de méthode.

Shared Function GetObject() As Object 
    Return Nothing 
End Function 

Shared Sub SetObject(ByVal obj As Object)
End Sub 

Shared Function GetString() As String 
    Return "" 
End Function 

Shared Sub SetString(ByVal str As String)

End Sub 

Shared Sub Test()
    ' Covariance. A delegate specifies a return type as object, 
    ' but you can assign a method that returns a string. 
    Dim del As Func(Of Object) = AddressOf GetString

    ' Contravariance. A delegate specifies a parameter type as string, 
    ' but you can assign a method that takes an object. 
    Dim del2 As Action(Of String) = AddressOf SetObject
End Sub
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 .NET Framework 4 et Visual Studio 2010, C# et Visual Basic prennent tous deux en charge la covariance et la contravariance dans les interfaces et les délégués génériques et autorisent la conversion implicite des paramètres de type générique. Pour plus d'informations, consultez Variance dans les interfaces génériques (C# et Visual Basic) et Variance dans les délégués (C# et Visual Basic).

L'exemple de code suivant décrit une conversion de référence implicite pour les interfaces génériques.

Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;

Une interface ou un délégué générique est appelé variant si ses paramètres génériques sont déclarés covariant ou contravariant. C# et Visual Basic vous permettent de créer vos propres interfaces et délégués variants. Pour plus d'informations, consultez Création d'interfaces génériques de type variant (C# et Visual Basic) et Variance dans les délégués (C# et Visual Basic).

Rubriques connexes

Titre

Description

Variance dans les interfaces génériques (C# et Visual Basic)

Décrit la covariance et la contravariance dans les interfaces génériques et fournit une liste d'interfaces génériques variantes dans le .NET Framework.

Création d'interfaces génériques de type variant (C# et Visual Basic)

Indique comment créer des interfaces variantes personnalisées.

Utilisation de la variance dans les interfaces pour les collections génériques (C# et Visual Basic)

Indique comment la prise en charge de la covariance et la contravariance dans les interfaces IEnumerable et IComparable peut vous aider à réutiliser le code.

Variance dans les délégués (C# et Visual Basic)

Décrit 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 variants dans le .NET Framework.

Utilisation de la variance dans les délégués (C# et Visual Basic)

Indique 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 les signatures de méthode aux types délégués.

Utilisation de la variance pour les délégués génériques Func et Action (C# et Visual Basic)

Indique 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 le code.