Rozptyl v obecných rozhraních (Visual Basic)

Rozhraní .NET Framework 4 zavedlo podporu odchylek pro několik existujících obecných rozhraní. Podpora rozptylu umožňuje implicitní převod tříd, které implementují tato rozhraní. Nyní jsou variantou následující rozhraní:

Kovariance umožňuje metodě mít odvozenější návratový typ, než který definuje parametr obecného typu rozhraní. Chcete-li ilustrovat kovarianci funkce, zvažte tato obecná rozhraní: IEnumerable(Of Object) a IEnumerable(Of String). Rozhraní IEnumerable(Of String) nedědí IEnumerable(Of Object) rozhraní. String Typ však zdědí Object typ a v některých případech můžete chtít přiřadit objekty těchto rozhraní k sobě navzájem. To je znázorněno v následujícím příkladu kódu.

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

V dřívějších verzích rozhraní .NET Framework tento kód způsobí chybu kompilace v jazyce Visual Basic s Option Strict On. Nyní ale můžete místo stringsobjects, jak je znázorněno v předchozím příkladu, protože IEnumerable<T> rozhraní je kovariantní.

Kontravariance umožňuje metodě mít typy argumentů, které jsou méně odvozeny, než které specifikuje obecný parametr rozhraní. Chcete-li ilustrovat kontravariance, předpokládejme, že jste vytvořili BaseComparer třídu pro porovnání instancí BaseClass třídy. Třída BaseComparer implementuje rozhraní IEqualityComparer(Of BaseClass). Vzhledem k tomu, že IEqualityComparer<T> rozhraní je nyní kontravariantní, můžete použít BaseComparer k porovnání instancí tříd, které dědí BaseClass třídu. To je znázorněno v následujícím příkladu kódu.

' 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

Další příklady naleznete v tématu Použití rozptylu v rozhraních pro obecné kolekce (Visual Basic).

Variance v obecných rozhraních je podporována pouze pro odkazové typy. Typy hodnot nepodporují odchylku. Například IEnumerable(Of Integer) nelze implicitně převést na IEnumerable(Of Object), protože celá čísla jsou reprezentována typem hodnoty.

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

Je také důležité si uvědomit, že třídy, které implementují variantní rozhraní, jsou stále invariantní. Ačkoli například List<T> implementuje kovariantní rozhraní IEnumerable<T>, nelze implicitně převést List(Of Object) na List(Of String). To je znázorněno v následujícím příkladu kódu.

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

Viz také