2

一直在阅读并检查其他问题,但不理解/似乎无法在其他任何地方找到我的答案。

假设以下

Public Interface IAudit
Public Class FamilyAudit implements IAudit
Public Class MemberAudit implements IAudit
Public Class AuditPair(Of T As IAudit)

Dim myList as new List(of AuditPair(of IAudit))
Dim famAuditPair as new AuditPair(of FamilyAudit)
Dim memAuditPair as new AuditPair(of MemberAudit)

' This fails
myList.Add(famAuditPair)
myList.Add(memAuditPair)

我收到编译器错误,即 auditPairs 无法隐式转换为 AuditPair(IAudit 的)。这看起来像 co/contra 方差。
MSDN 文档说,从 4.0 开始,列表应该支持方差。

我错过了什么?

4

1 回答 1

2

新的in/out方差特性特别适用于两种情况:

  • 接口
  • 代表

它不适用于具体类型列表List<T>。此外,“列表”本质上是不变的,因为“添加”和“枚举”在任一方向上都是相互不兼容的。但是,作为序列的列表是协变的。考虑:

var list = new List<FamilyAudit>();
IEnumerable<IAudit> seq = list; // <=== covariance; the list is
                                // IEnumerable<FamilyAudit>, which
                                // can be compatible with
                                // IEnumerable<IAudit>

请注意,这仅适用于 .NET 4.0 及更高版本;在早期版本中,它会拒绝编译,说:

无法将类型“System.Collections.Generic.List”隐式转换为“System.Collections.Generic.IEnumerable”。存在显式转换(您是否缺少演员表?)

那是因为在4.0之前,接口是IEnumerable<T>,而不是必要的IEnumerable<out T>

于 2012-11-28T09:17:40.207 回答