以下是一些伴随我的问题的代码:
interface IFirmEntity { }
interface IClient : IFirmEntity { }
class Repository
{
public Task<ReadOnlyCollection<IClient>> GetClientsAsync()
{
throw new NotImplementedException();
}
public ReadOnlyCollection<IClient> GetClients()
{
throw new NotImplementedException();
}
}
现在,如果我编写以下代码,则会收到下面描述的错误:
var repo = new Repository();
// works b/c of covariance on IReadOnlyCollection<T>
IReadOnlyCollection<IFirmEntity> a1 = repo.GetClients();
// does not work b/c of invariance of Task<T>
Task<IReadOnlyCollection<IFirmEntity>> a2 = repo.GetClientsAsync();
(CS0029)无法隐式转换类型 'System.Threading.Tasks.Task>' 至 'System.Threading.Tasks.Task>'
因此,如果IReadOnlyCollection<T>
在T
上是协变的,而Task<T>
在T
上是不变的,则Task<IReadOnlyCollection<IFirmEntity>>
无效,即使看起来应该如此。
嵌套的泛型与协方差组合无法编译的技术原因是什么?
此外,作为一个旁注,下面的代码可以正常工作,但是,除非我理解不正确,否则我假设编译器足够聪明,可以评估异步/等待状态机中使用的协方差:< / p>
var mech = new SomeMechanism();
// this works just fine.
Task<IReadOnlyCollection<IFirmEntity>> a3 =
mech.DoAsync(async () => await repo.GetClientsAsync()); // No error.
class SomeMechanism
{
public Task DoAsync(Func<Task<IReadOnlyCollection<IFirmEntity>>> someOperation)
=> throw new NotImplementedException();
}