2016-07-06 116 views
4

我有一个类(示出简化的样品和仅有的相关部件)为什么异步方法返回类型不能从任务派生?

public class AsyncScenario : Task<Scenario> 
{ 
    public async AsyncScenario Test(Func<Task> action) 
    { 
     return await this;   
    } 
} 

我不能编译此,因为该方法的返回类型:

编译错误CS1983:“的返回类型的异步方法必须是void,Task或Task < T>”

为什么不允许异步方法返回来自Task<T>派生的类?

+1

编译器应该如何实例化你的DerivedTask ?但是,在这种情况下,没有理由使用'async'。你可以删除'await'和'async',它可以正常工作。 – Aron

回答

7

因为C#规格是这么说的? Eric Lippert或其他一些语言设计团队成员在之内时,你不会得到比这更好的答案。其他任何事情都将是纯粹的猜测和舆论。

也就是说,假设在async方法中,返回值由return语句暗示,那么您认为规范规则应该在这样一个示例中是什么?显然await this解析为Scenario对象... C#编译器应该如何从该表达式类型合成新的AsyncScenario对象?

我想你可能会想出一些额外的规则,你可以在规范中明确提供一些机制。但是在我看来,这些规则会比现在规范中存在的规则复杂得多,其中规则所代表的规则更为复杂,其中返回类型始终是规范作者已知的类型,并且具有明确的规则来创建第一次方法返回,同样重要的是,改变执行return语句的状态。

这些规则似乎很可能存在,只是因为否则就需要付出过多的努力,并且会显着增加编译器的复杂性以及编译器中错误的可能性。


†说到这,有点搜索挖出了金:Why must async methods return Task?,由卢西恩Wischik,语言设计师VB.NET写的(但文章同样适用于C#)。另请参阅Jon Skeet在Using a generic type as a return type of an async method的回答。

+1

[“任意类任务返回类型”正在考虑](https://github.com/ljw1004/roslyn/blob/features/async-return/docs/specs/feature%20-%20arbitrary%20async%20returns。 MD)。大概不会很快,但是我们将来可能会有这样的时间。 –

+2

@StephenCleary:我昨天和Lucian一起吃午饭,他告诉我他仍然在积极追求这个功能,所以它的优势很不错,当然也不会有任何承诺。 –

1

您可以等待任何方法,与GetAwaiter方法返回类型:

public static async Task<Scenario> Test() 
    { 
     return await new AsyncScenario(); 
    } 

    public class AsyncScenario 
    { 
     public TaskAwaiter<Scenario> GetAwaiter() 
     { 
      return new TaskAwaiter<Scenario>(); 
     } 
    } 
+0

您的'Test()'方法返回'任务'而不是'AsyncScenario'。那么,你的答案如何解释为什么_return type_方法不能是'AsyncScenario'? –

相关问题