.NET Framework 4 引進了數個現有泛型介面的變異數支援。 變異數支援可讓您隱含轉換實作這些介面的類別。 下列介面現在是變體:
IEnumerable<T> (T 是共變數)
IEnumerator<T> (T 是共變數)
IQueryable<T> (T 是共變數)
IGrouping<TKey,TElement> (
TKey和TElement是共變數)IComparer<T> (T 是反變數)
IEqualityComparer<T> (T 是反變數)
IComparable<T> (T 是反變數)
協變性允許方法具有比介面的泛型型別參數所定義的更衍生的返回型別。 若要說明共變數功能,請考慮下列泛型介面: IEnumerable(Of Object) 和 IEnumerable(Of String)。 介面 IEnumerable(Of String) 不會繼承 IEnumerable(Of Object) 介面。 不過, String 此類型會繼承 Object 類型,在某些情況下,您可能會想要將這些介面的物件指派給彼此。 如下列程式代碼範例所示。
Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings
在舊版 .NET Framework 中,這段程式碼會在 Visual Basic 中造成編譯錯誤,並顯示 Option Strict On。 但現在您可以使用 strings ,而不是 objects,如上一個範例所示,因為 IEnumerable<T> 介面是covariant。
反變形允許方法的引數類型比介面的泛型參數所指定的類型衍生程度更低。 為了說明反變數,假設您已建立類別 BaseComparer 來比較 類別的 BaseClass 實例。
BaseComparer 類別會實作 IEqualityComparer(Of BaseClass) 介面。 因為IEqualityComparer<T>介面現在是逆變型,因此您可以使用BaseComparer來比較繼承BaseClass類別的實例。 如下列程式代碼範例所示。
' Simple hierarchy of classes.
Class BaseClass
End Class
Class DerivedClass
Inherits BaseClass
End Class
' Comparer class.
Class BaseComparer
Implements IEqualityComparer(Of BaseClass)
Public Function Equals1(ByVal x As BaseClass,
ByVal y As BaseClass) As Boolean _
Implements IEqualityComparer(Of BaseClass).Equals
Return (x.Equals(y))
End Function
Public Function GetHashCode1(ByVal obj As BaseClass) As Integer _
Implements IEqualityComparer(Of BaseClass).GetHashCode
Return obj.GetHashCode
End Function
End Class
Sub Test()
Dim baseComparer As IEqualityComparer(Of BaseClass) = New BaseComparer
' Implicit conversion of IEqualityComparer(Of BaseClass) to
' IEqualityComparer(Of DerivedClass).
Dim childComparer As IEqualityComparer(Of DerivedClass) = baseComparer
End Sub
如需更多範例,請參閱 在泛型集合的介面中使用變數 (Visual Basic) 。
泛型介面的變異數只適用於參考類型。 實值類型不支援變異數。 例如, IEnumerable(Of Integer) 無法隱含轉換成 IEnumerable(Of Object),因為整數是由實值型別表示。
Dim integers As IEnumerable(Of Integer) = New List(Of Integer)
' The following statement generates a compiler error
' with Option Strict On, because Integer is a value type.
' Dim objects As IEnumerable(Of Object) = integers
請務必記住,實作 Variant 介面的類別仍然不可變。 例如,雖然 List<T> 實作協變介面 IEnumerable<T>,但您無法將 List(Of Object) 隱式轉換為 List(Of String)。 下列程式代碼範例會說明這一點。
' The following statement generates a compiler error
' because classes are invariant.
' Dim list As List(Of Object) = New List(Of String)
' You can use the interface object instead.
Dim listObjects As IEnumerable(Of Object) = New List(Of String)