Task 和 Task<T> 可以互换吗?
Are Task and Task<T> Interchangeable?
我 运行 在尝试调用特定方法重载时遇到了输入情况,现在我很好奇:为什么以下不会引发编译错误?
var a = (Task<Task>) (Task) null; // fine.
var b = (Func<Task<Task>>) (Func<Task>) null; // fine.
var c = (Task<Task<Task>>) (Task<Task>) null; // compilation error.
我预计所有这些示例都会失败。
第三行错误(c
):
Cannot cast expression of type 'System.Threading.Tasks.Task<System.Threading.Tasks.Task>' to type 'Task<Task<Task>>'
你的第一行有点像 (int) (object) 1
,这是完全合法的,因为一切(包括 int
)都来自 Object
.
你的第二行是同样的事情,但是逆变在起作用。
第三行失败,因为Task<T>
的T
参数没有设置协方差(事实上,不可能是因为Task<T>
是一个class,不是接口或委托)。它适用于 Func<TResult>
,因为 Func<TResult>
是 设置的协方差(即声明为 Func<out TResult>
)。任务可能被设计为故意禁止这样做,或者他们忘记这样做。
这是 的外推:
对于 a
:Task<T>
派生自 Task
,所以这没问题。
对于 b
:Func
是具有协变性的委托,因此代表我们将 Task
隐式转换为 Task<T>
。 Func
没有改变,因此没问题。
对于 c
:Task
不能使用协变类型参数,因为它是 class,并且 Task<Task<T>>
不是从 Task<T>
派生的,因此这不行。
我 运行 在尝试调用特定方法重载时遇到了输入情况,现在我很好奇:为什么以下不会引发编译错误?
var a = (Task<Task>) (Task) null; // fine.
var b = (Func<Task<Task>>) (Func<Task>) null; // fine.
var c = (Task<Task<Task>>) (Task<Task>) null; // compilation error.
我预计所有这些示例都会失败。
第三行错误(c
):
Cannot cast expression of type 'System.Threading.Tasks.Task<System.Threading.Tasks.Task>' to type 'Task<Task<Task>>'
你的第一行有点像 (int) (object) 1
,这是完全合法的,因为一切(包括 int
)都来自 Object
.
你的第二行是同样的事情,但是逆变在起作用。
第三行失败,因为Task<T>
的T
参数没有设置协方差(事实上,不可能是因为Task<T>
是一个class,不是接口或委托)。它适用于 Func<TResult>
,因为 Func<TResult>
是 设置的协方差(即声明为 Func<out TResult>
)。任务可能被设计为故意禁止这样做,或者他们忘记这样做。
这是
对于 a
:Task<T>
派生自 Task
,所以这没问题。
对于 b
:Func
是具有协变性的委托,因此代表我们将 Task
隐式转换为 Task<T>
。 Func
没有改变,因此没问题。
对于 c
:Task
不能使用协变类型参数,因为它是 class,并且 Task<Task<T>>
不是从 Task<T>
派生的,因此这不行。