泛型接口中的变体(Visual Basic)Variance in Generic Interfaces (Visual Basic)
.NET Framework 4 引入了对多个现有泛型接口的变体支持。.NET Framework 4 introduced variance support for several existing generic interfaces. 变体支持允许实现这些接口的类进行隐式转换。Variance support enables implicit conversion of classes that implement these interfaces. 下面的接口现在是变体:The following interfaces are now variant:
IEnumerable<T>(T 是协变)IEnumerable<T> (T is covariant)
IEnumerator<T>(T 是协变)IEnumerator<T> (T is covariant)
IQueryable<T>(T 是协变)IQueryable<T> (T is covariant)
IGrouping<TKey,TElement>(
TKey
和TElement
都是协变)IGrouping<TKey,TElement> (TKey
andTElement
are covariant)IComparer<T>(T 是逆变)IComparer<T> (T is contravariant)
IEqualityComparer<T>(T 是逆变)IEqualityComparer<T> (T is contravariant)
IComparable<T>(T 是逆变)IComparable<T> (T is contravariant)
协变允许方法具有的返回类型比接口的泛型类型参数定义的返回类型的派生程度更大。Covariance permits a method to have a more derived return type than that defined by the generic type parameter of the interface. 若要演示协变功能,请考虑以下泛型接口:IEnumerable(Of Object)
和 IEnumerable(Of String)
。To illustrate the covariance feature, consider these generic interfaces: IEnumerable(Of Object)
and IEnumerable(Of String)
. IEnumerable(Of String)
接口不继承 IEnumerable(Of Object)
接口。The IEnumerable(Of String)
interface does not inherit the IEnumerable(Of Object)
interface. 但是,String
类型会继承 Object
类型,在某些情况下,建议为这些接口互相指派彼此的对象。However, the String
type does inherit the Object
type, and in some cases you may want to assign objects of these interfaces to each other. 下面的代码示例对此进行了演示。This is shown in the following code example.
Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings
在 .NET Framework 的早期版本中,此代码会在 Visual Basic 中导致 Option Strict On
编译错误。In earlier versions of the .NET Framework, this code causes a compilation error in Visual Basic with Option Strict On
. 但现在可使用 strings
代替 objects
,如上例所示,因为 IEnumerable<T> 接口是协变接口。But now you can use strings
instead of objects
, as shown in the previous example, because the IEnumerable<T> interface is covariant.
逆变允许方法具有的实参类型比接口的泛型形参定义的类型的派生程度更小。Contravariance permits a method to have argument types that are less derived than that specified by the generic parameter of the interface. 若要演示逆变,假设已创建了 BaseComparer
类来比较 BaseClass
类的实例。To illustrate contravariance, assume that you have created a BaseComparer
class to compare instances of the BaseClass
class. BaseComparer
类实现 IEqualityComparer(Of BaseClass)
接口。The BaseComparer
class implements the IEqualityComparer(Of BaseClass)
interface. 因为 IEqualityComparer<T> 接口现在是逆变接口,因此可使用 BaseComparer
比较继承 BaseClass
类的类的实例。Because the IEqualityComparer<T> interface is now contravariant, you can use BaseComparer
to compare instances of classes that inherit the BaseClass
class. 下面的代码示例对此进行了演示。This is shown in the following code example.
' 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)。For more examples, see Using Variance in Interfaces for Generic Collections (Visual Basic).
只有引用类型才支持使用泛型接口中的变体。Variance in generic interfaces is supported for reference types only. 值类型不支持变体。Value types do not support variance. 例如,无法将 IEnumerable(Of Integer)
隐式转换为 IEnumerable(Of Object)
,因为整数由值类型表示。For example, IEnumerable(Of Integer)
cannot be implicitly converted to IEnumerable(Of Object)
, because integers are represented by a value type.
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
还需记住,实现变体接口的类仍是固定类。It is also important to remember that classes that implement variant interfaces are still invariant. 例如,虽然 List<T> 实现协变接口 IEnumerable<T>,但不能将 List(Of Object)
隐式转换为 List(Of String)
。For example, although List<T> implements the covariant interface IEnumerable<T>, you cannot implicitly convert List(Of Object)
to List(Of String)
. 此内容将在以下代码示例中说明。This is illustrated in the following code example.
' 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)
另请参阅See also
反馈
正在加载反馈...