使用generics类型作为异步方法的返回类型
之前的一个问题让我想知道为什么以下方法会引发编译时错误:
异步方法的返回类型必须为void,Task或Task
public async T MyMethodAsync() where T : Task { // Irrelevant code here which returns a Task }
既然我们在编译时知道T总是一个Task
或派生类型,为什么这不起作用呢?
编辑
我问的原因是方法可能返回Task
或Task
。 假设该方法可以返回,我不想重复代码。
当然,这完全是理论上的,而不是用于生产目的。
编辑2
Lucian Wischik发现了一篇很棒的文章: 为什么必须异步返回Task
三个问题:
-
仅仅因为
T
是“Task
或派生类型”并不意味着它是Task
或Task
。 如果我调用MyMethodAsync
MyCustomTask
从Task
派生的话,你会期待什么? -
编译器在编译方法时需要知道它是否正在构建一个返回
Task
或Task
的状态机 – 它在不同的情况下使用不同的helper类 -
如果异步方法的返回类型为
Task
,则任何return
语句都不能指定值; 如果它的返回类型为Task
任何return
语句都必须指定一个可隐式转换为T
。 如何在MyMethodAsync
中工作? 这有点像说“我的方法void
或返回T
– 您可以决定何时调用它”。
目前还不清楚你在这里想要达到的目标,但基本上这不会起作用。
我想不出MyMethodAsync
的有效定义,它允许它返回从Task
派生的genericsT
,而不知道在编译时该类型是什么或采用某种类型的参数。
如果您确实正在返回Task
或Task
那么您可以更新您的签名以反映该事实并避免该问题。
如果你真的需要从Task
派生的某种类型,那么你需要重写你的逻辑而不是返回Task
或Task
并包装其他类型。 假设这是不可接受的,您将需要删除async
并自己处理状态机。