gpt4 book ai didi

c# - Task 可以/应该包装在 C# 5.0 等待中,它在 TResult 中是协变的吗?

转载 作者:可可西里 更新时间:2023-11-01 08:39:45 26 4
gpt4 key购买 nike

我非常喜欢使用 C# 5.0 异步编程。然而,有几个地方更新旧代码以与 TAP 模型保持一致给我带来了问题。

这是其中之一 - 我不确定为什么 Task<TResult> 在 TResult 中不是协变的,但在尝试更新协变接口(interface)以从同步模式移动到异步模式时,它给我带来了问题:

旧代码:

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 接口(interface),但我想我可以创建一个并创建一个扩展方法来转换为包装的、协变的、可等待的任务对象。还是我做错了?

最佳答案

Task<T>T 中不能协变,因为它是一个类。只有接口(interface)和委托(delegate)可以有泛型变化。

至于是否值得进行包装...我想这取决于您在项目中使用了多少协方差。我怀疑随着时间的推移,您会发​​现所有的包装和展开都令人困惑,老实说 - 如果只是采取消除协方差的打击不是不好的话,我会这样做。

关于c# - Task<TResult> 可以/应该包装在 C# 5.0 等待中,它在 TResult 中是协变的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12204755/

26 4 0