使用generics类型作为异步方法的返回类型

之前的一个问题让我想知道为什么以下方法会引发编译时错误:

异步方法的返回类型必须为void,Task或Task

public async T MyMethodAsync() where T : Task { // Irrelevant code here which returns a Task } 

既然我们在编译时知道T总是一个Task或派生类型,为什么这不起作用呢?

编辑

我问的原因是方法可能返回TaskTask 。 假设该方法可以返回,我不想重复代码。

当然,这完全是理论上的,而不是用于生产目的。

编辑2

Lucian Wischik发现了一篇很棒的文章: 为什么必须异步返回Task

三个问题:

  • 仅仅因为T是“ Task或派生类型”并不意味着它是TaskTask 。 如果我调用MyMethodAsync MyCustomTaskTask派生的话,你会期待什么?

  • 编译器在编译方法时需要知道它是否正在构建一个返回TaskTask的状态机 – 它在不同的情况下使用不同的helper类

  • 如果异步方法的返回类型为Task ,则任何return语句都不能指定值; 如果它的返回类型为Task任何return语句都必须指定一个可隐式转换为T 。 如何在MyMethodAsync中工作? 这有点像说“我的方法void或返回T – 您可以决定何时调用它”。

目前还不清楚你在这里想要达到的目标,但基本上这不会起作用。

我想不出MyMethodAsync的有效定义,它允许它返回从Task派生的genericsT ,而不知道在编译时该类型是什么或采用某种类型的参数。

如果您确实正在返回TaskTask那么您可以更新您的签名以反映该事实并避免该问题。

如果你真的需要从Task派生的某种类型,那么你需要重写你的逻辑而不是返回TaskTask并包装其他类型。 假设这是不可接受的,您将需要删除async并自己处理状态机。