问题描述
我真的很喜欢用C#5.0异步编程工作。不过,也有一些地方,更新旧code是与TAP模型一致导致的问题对我来说。
下面是其中之一 - 我不知道到底为什么不TResult协变,但试图更新协接口从同步移动到异步模式时,它造成的问题对我来说:
旧code:
公共接口IInitializable<出T> // **出通用改性剂**
{
///<总结>
///布尔值,表明如果类是准备
///< /总结>
布尔将IsInitialized {搞定; } ///<总结>
///例如呼叫通过电流参数初始化
///驱动程序初始化可以在默认的构造函数如果需要做
///< /总结>
ŧ初始化();
}
新的code(不会编译):
公共接口IAsyncInitializable<出T> // **出通用改性剂...破**
{
///<总结>
///布尔值,表明如果类是准备
///< /总结>
布尔将IsInitialized {搞定; } ///<总结>
///例如呼叫通过电流参数初始化
///驱动程序初始化可以在默认的构造函数如果需要做
///< /总结>
任务<出T> InitializeAsync(); // **休息,因为任务< TResult>在TResult不变**
}
时有解决这个合理的方式,而无需修改我的API得太厉害? (奖励:为什么任务不是协变?)。有没有IAwaitable接口,但我想我可以做一个,并创建转换成一个包裹,协变,awiatable任务对象的扩展方法。还是我做错了?
任务< T>
不能在 T被协变
,因为它是一个类。只有接口和委托可以有通用的差异。
至于它是否值得做包装......我想这取决于你有多少使用您的项目中的协方差。我怀疑你会发现所有的包装和展开随着时间的推移混乱,说实话 - 如果不是的太的坏只取去除协方差的打击,我会做到这一点。
I'm really enjoying working with C# 5.0 asynchronous programming. However, there are a few places where updating old code to be consistent with the TAP model is causing problems for me.
Here's one of them - I'm not sure exactly why Task<TResult>
is not covariant in TResult, but it's causing problems for me when trying to update a covariant interface to move from a synchronous to an asychronous pattern:
Old code:
public interface IInitializable<out T> // ** out generic modifier **
{
/// <summary>
/// Boolean to indicate if class is ready
/// </summary>
bool IsInitialized { get; }
/// <summary>
/// Calls for instance to be initialized using current parameters
/// Driver initialization can be done in the default constructor if desired
/// </summary>
T Initialize();
}
New code (won't compile):
public interface IAsyncInitializable<out T> // ** out generic modifier...broken **
{
/// <summary>
/// Boolean to indicate if class is ready
/// </summary>
bool IsInitialized { get; }
/// <summary>
/// Calls for instance to be initialized using current parameters
/// Driver initialization can be done in the default constructor if desired
/// </summary>
Task<out T> InitializeAsync(); // ** breaks because Task<TResult> is invariant in TResult **
}
Is there is a reasonable way around this without modifying my APIs too drastically? (Bonus: why is Task not covariant?). There's no IAwaitable interface, but I suppose I could make one and create an extension method that converts to a wrapped, covariant, awiatable task object. Or am I doing it wrong?
Task<T>
can't be covariant in T
, because it's a class. Only interfaces and delegates can have generic variance.
As for whether it's worth doing the wrapping... I guess that depends on how much you use the covariance within your project. I suspect you'll find all the wrapping and unwrapping confusing over time, to be honest - if it's not too bad to just take the hit of removing the covariance, I'd do that.
这篇关于可以/应任务&LT; TResult&GT;在C#5.0 awaitable这是协变的TResult被包裹?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!