作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我非常喜欢使用 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/
COW 不是奶牛,是 Copy-On-Write 的缩写,这是一种是复制但也不完全是复制的技术。 一般来说复制就是创建出完全相同的两份,两份是独立的: 但是,有的时候复制这件事没多大必要
我是一名优秀的程序员,十分优秀!