共變數和反變數 (C# 和 Visual Basic)

在 C# 和 Visual Basic 中,共變數和反變數允許陣列型別、委派型別和泛型型別引數的隱含參考轉換。 共變數會保留指派相容性,而共變異數則將其反轉。

下列程式碼示範共變數和反變數之間的指派相容性差異。

' 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;

陣列的共變數可讓衍生程度較大之型別的陣列隱含轉換為衍生程度較小之型別的陣列。 但這個作業不是型別安全的,如下列程式碼範例所示。

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;

共變數和反變數支援方法群組,允許方法簽章與委派型別相符。 這樣您可以指派給委派的,就不只是具有相符簽章的方法,而且還有與委派型別指定的型別相比,傳回衍生程度較大型別 (共變數) 或接受衍生程度較小型別 (Contravariance) 的方法。 如需詳細資訊,請參閱委派中的變異數 (C# 和 Visual Basic)在委派中使用變異數 (C# 和 Visual Basic)

下列程式碼範例示範共變數和反變數對方法群組的支援。

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;
}

在 .NET Framework 4 和 Visual Studio 2010 中,C# 和 Visual Basic 都會在泛型介面及委派中支援共變數和 Contravariance,而且允許泛型型別參數的隱含轉換。 如需詳細資訊,請參閱泛型介面中的變異數 (C# 和 Visual Basic)委派中的變異數 (C# 和 Visual Basic)

下列程式碼範例示範泛型介面的隱含參考轉換。

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;

如果泛型介面或委派將其泛型參數宣告為 Covariant 或 Contravariant,此泛型介面或委派即稱為 Variant。 C# 和 Visual Basic 都可以讓您建立自己的 Variant 介面和委派。 如需詳細資訊,請參閱建立 Variant 泛型介面 (C# 和 Visual Basic)委派中的變異數 (C# 和 Visual Basic)

相關主題

標題

描述

泛型介面中的變異數 (C# 和 Visual Basic)

討論泛型介面中的共變數和 Contravariance,並提供 .NET Framework 中的 Variant 泛型介面清單。

建立 Variant 泛型介面 (C# 和 Visual Basic)

示範如何建立自訂 Variant 介面。

針對泛型集合使用介面中的變異數 (C# 和 Visual Basic)

示範 IEnumerable<T>IComparable<T> 介面中的共變數與 Contravariance 支援如何協助您重複使用程式碼。

委派中的變異數 (C# 和 Visual Basic)

討論泛型及非泛型委派中的共變數和 Contravariance,並提供 .NET Framework 中的 Variant 泛型委派清單。

在委派中使用變異數 (C# 和 Visual Basic)

示範如何使用非泛型委派中的共變數與 Contravariance 支援,使方法簽章與委派型別相符。

針對 Func 與 Action 委派使用變異數 (C# 和 Visual Basic)

示範 Func 及 Action 委派中的共變數與 Contravariance 支援如何協助您重複使用程式碼。