Covariance and Contravariance (Visual Basic)

In Visual Basic, covariance and contravariance enable implicit reference conversion for array types, delegate types, and generic type arguments. Covariance preserves assignment compatibility and contravariance reverses it.

The following code demonstrates the difference between assignment compatibility, covariance, and 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

Covariance for arrays enables implicit conversion of an array of a more derived type to an array of a less derived type. But this operation isn't type safe, as shown in the following code example.

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

Covariance and contravariance support for method groups allows for matching method signatures with delegate types. This matching enables you to assign to a delegate not only a method that has a matching signature, but also a method that:

  • Returns a more derived type (covariance) than the return type specified by the delegate type.
  • Accepts parameters that have less derived types (contravariance) than those specified by the delegate type.

For more information, see Variance in Delegates (Visual Basic) and Using Variance in Delegates (Visual Basic).

The following code example shows covariance and contravariance support for method groups.

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

In .NET Framework 4 or later, Visual Basic supports covariance and contravariance in generic interfaces and delegates and allows for implicit conversion of generic type parameters. For more information, see Variance in Generic Interfaces (Visual Basic) and Variance in Delegates (Visual Basic).

The following code example shows implicit reference conversion for generic interfaces.

Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings

A generic interface or delegate is called variant if its generic parameters are declared covariant or contravariant. Visual Basic enables you to create your own variant interfaces and delegates. For more information, see Creating Variant Generic Interfaces (Visual Basic) and Variance in Delegates (Visual Basic).

Title Description
Variance in Generic Interfaces (Visual Basic) Discusses covariance and contravariance in generic interfaces and provides a list of variant generic interfaces in the .NET Framework.
Creating Variant Generic Interfaces (Visual Basic) Shows how to create custom variant interfaces.
Using Variance in Interfaces for Generic Collections (Visual Basic) Shows how covariance and contravariance support in the IEnumerable<T> and IComparable<T> interfaces can help you reuse code.
Variance in Delegates (Visual Basic) Discusses covariance and contravariance in generic and non-generic delegates and provides a list of variant generic delegates in the .NET Framework.
Using Variance in Delegates (Visual Basic) Shows how to use covariance and contravariance support in non-generic delegates to match method signatures with delegate types.
Using Variance for Func and Action Generic Delegates (Visual Basic) Shows how covariance and contravariance support in the Func and Action delegates can help you reuse code.