【发布时间】:2012-08-25 15:30:58
【问题描述】:
我真的很喜欢使用 C# 5.0 异步编程。但是,在某些地方更新旧代码以与 TAP 模型保持一致会给我带来问题。
这是其中之一 - 我不确定为什么 Task<TResult> 在 TResult 中不是协变的,但是当我尝试更新协变接口以从同步模式转变为异步模式时,这给我带来了问题:
旧代码:
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();
}
新代码(不会编译):
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<T> InitializeAsync(); // ** breaks because Task<TResult> is invariant in TResult **
}
是否有一种合理的方法可以解决这个问题,而无需过度修改我的 API? (奖励:为什么 Task 不是协变的?)。没有 IAwaitable 接口,但我想我可以制作一个并创建一个扩展方法,该方法转换为一个包装好的、协变的、可等待的任务对象。还是我做错了?
【问题讨论】:
-
顺便说一句,即使
Task是协变接口,您的代码也无法编译。正确的版本是Task<T> InitializeAsync();(该行没有out修饰符)。 -
一个很好的观点。我在 VS 中更正了这一点,但忘记编辑 SO。
标签: c# task-parallel-library covariance async-await c#-5.0