なぜasync
メソッドが Task オブジェクトを返すように指定する必要があるのか疑問に思います。
それを指定することは、キーワードと重複しているように見えます。また、実際にはオブジェクトasync
を作成していないため、混乱を招きます。Task
私が理解しているように、コンパイラは Task オブジェクトの作成に必要なコードを発行します (await 呼び出しであるか、戻り値を新しい Task でラップするかに関係なく)。
宣言型と戻り型の不一致はあまり好きではありません。
なぜasync
メソッドが Task オブジェクトを返すように指定する必要があるのか疑問に思います。
それを指定することは、キーワードと重複しているように見えます。また、実際にはオブジェクトasync
を作成していないため、混乱を招きます。Task
私が理解しているように、コンパイラは Task オブジェクトの作成に必要なコードを発行します (await 呼び出しであるか、戻り値を新しい Task でラップするかに関係なく)。
宣言型と戻り型の不一致はあまり好きではありません。
これは実際には問題ではありません。これは暴言であり、StackOverflow には特に適していません。
宣言型と戻り値の型の不一致はあまり好きではありません。
文句を言いたいなら、ブログを始めて、それについて文句を言いましょう。それを質問として再定式化しましょう:
メソッドによって返される宣言された型は
async
、たとえば である可能性がありますTask<int>
が、そのメソッドのステートメントによって返される式は、 ではなくreturn
に暗黙的に変換可能でなければなりint
ませんTask<int>
。これは混乱を招く可能性があります。この動作を正当化する設計原則は何ですか?
これが混乱を招く可能性があることは間違いありません。async
メソッドは、私たちが 1 つのものとして考えるのに非常に慣れている 2 つのものを分離するため、混乱を招きます。それらの2つのことは次のとおりです。
同期メソッドでは、呼び出し元での再開ポイントが同期メソッドの継続であるため、これら 2 つのことは常に同じです。しかし、非同期メソッドの要点は、呼び出し元のコードがメソッドの継続ではないということです。メソッドの継続は、それに関連付けられたタスクの継続を設定することによって制御されます。
そのため、宣言された戻り値の型とreturn
ステートメントに指定された型が異なります。呼び出し元は を必要としてTask<int>
いますが、メソッドの継続int
は を必要としています。このreturn
ステートメントは、メソッドが同期であるか非同期であるかに関係なく、「このメソッドは完了しました。この値を継続に渡します」という意味です。
public async int MyMethodAsync()
実際に を返すメソッドとして自動的にコンパイルされない理由を尋ねているようですTask<int>
。
答えは、驚くことの少ない原則です。メソッド シグネチャで宣言された戻り値の型は、常に実際の戻り値の型です。
このようにして、メソッド宣言を読むときに、修飾子を調べたり特別なルールを覚えたりしなくても、メソッドを呼び出すときに見られる実際の戻り値の型を常に知ることができます。