我真的很喜欢使用 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 接口,但我想我可以制作一个并创建一个扩展方法,该方法转换为一个包装好的、协变的、可等待的任务对象。还是我做错了?