2016-07-06 124 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'? –

相關問題