Odchylka v obecné rozhraní (C# a Visual Basic)
.NET Framework 4 zavádí podporu odchylka pro několik stávající obecné rozhraní.Podpora odchylka umožňuje implicitní převod třídy, které implementují těchto rozhraní.Následující rozhraní jsou nyní varianty:
IEnumerable<T>(T je covariant)
IEnumerator<T>(T je covariant)
IQueryable<T>(T je covariant)
IGrouping<TKey, TElement>(TKey and TElement are covariant)
IComparer<T>(T je contravariant)
IEqualityComparer<T>(T je contravariant)
IComparable<T>(T je contravariant)
Kovariance umožňuje mít návratový typ odvozený více než obecný typ parametru rozhraní definuje metodu.Pro ilustraci funkce kovariance zvážit tyto obecné rozhraní: IEnumerable<Object> a IEnumerable<String> (IEnumerable(Of Object) a IEnumerable(Of String) v jazyce Visual Basic).IEnumerable<String> (IEnumerable(Of String) v jazyce Visual Basic) nedědí rozhraní IEnumerable<Object> rozhraní (IEnumerable(Of Object) v jazyce Visual Basic).Však String zdědí typ Object typu a v některých případech můžete chtít navzájem přiřadit objekty těchto rozhraní.To je ukázá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
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;
V předchozích verzích.NET Framework Tento kód způsobí chybu kompilace v jazyce C# a Visual Basic s Option Strict On.Ale nyní můžete použít strings namísto objects, jak je znázorněno v předchozím příkladu, protože IEnumerable<T> je covariant rozhraní.
Contravariance umožňuje metoda mít typy argumentů, které jsou odvozené nižší než určenou parametrem obecné rozhraní.Pro ilustraci contravariance předpokládá, že jste vytvořili BaseComparer porovnat instance třídy BaseClass třídy.BaseComparer Třída implementuje IEqualityComparer<BaseClass> rozhraní (IEqualityComparer(Of BaseClass) v jazyce Visual Basic).Protože IEqualityComparer<T> rozhraní je contravariant, můžete použít BaseComparer k porovnání instance tříd, které dědí BaseClass třídy.To je ukázá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
// Simple hierarchy of classes.
class BaseClass { }
class DerivedClass : BaseClass { }
// Comparer class.
class BaseComparer : IEqualityComparer<BaseClass>
{
public int GetHashCode(BaseClass baseInstance)
{
return baseInstance.GetHashCode();
}
public bool Equals(BaseClass x, BaseClass y)
{
return x == y;
}
}
class Program
{
static void Test()
{
IEqualityComparer<BaseClass> baseComparer = new BaseComparer();
// Implicit conversion of IEqualityComparer<BaseClass> to
// IEqualityComparer<DerivedClass>.
IEqualityComparer<DerivedClass> childComparer = baseComparer;
}
}
Další příklady naleznete v tématu Pomocí odchylka v rozhraní pro obecný kolekce (C# a Visual Basic).
Odchylka v obecné rozhraní je podporováno pouze typy odkazů.Typy hodnot odchylka nepodporují.Například IEnumerable<int> (IEnumerable(Of Integer) v jazyce Visual Basic) nelze implicitně převést na IEnumerable<object> (IEnumerable(Of Object) v jazyce Visual Basic), protože celá čísla představují typ 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
IEnumerable<int> integers = new List<int>();
// The following statement generates a compiler errror,
// because int is a value type.
// IEnumerable<Object> objects = integers;
Je také důležité si uvědomit, že jsou stále výchozí třídy, které implementují rozhraní typu variant.Například Ačkoli List<T> implementuje rozhraní covariant IEnumerable<T>, nelze implicitně převést List<Object> na List<String> (List(Of Object) na List(Of String) v jazyce Visual Basic).Tento postup je znázorněn 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)
// The following line generates a compiler error
// because classes are invariant.
// List<Object> list = new List<String>();
// You can use the interface object instead.
IEnumerable<Object> listObjects = new List<String>();
Viz také
Referenční dokumentace
Pomocí odchylka v rozhraní pro obecný kolekce (C# a Visual Basic)