This isn't really a question: it's more of a rant and therefore not particularly suitable for StackOverflow:
I don't really like the inconsistency between the declare type and the return type.
If you want to complain, start a blog and complain on that. Let's reformulate that as a question:
The declared type returned by an async
method might be, say Task<int>
but the expression returned by a return
statement in that method must be implicitly convertible to int
, not Task<int>
. This is potentially confusing. What design principle justifies this behaviour?
You are right that this is potentially confusing. It is confusing because async
methods separate two things that we are very used to thinking of as one thing. Those two things are:
- What type of object is returned when control resumes in the caller of this method?
- What type of object is passed from the method to its continuation? Remember that the continuation of a method is the code that runs when the method completes.
In synchronous methods those two things are always the same because the point of resumption in the caller is the continuation of a synchronous method. But the whole point of an asynchronous method is that the code in the caller is not the continuation of the method. The continuation of the method is controlled by setting the continuation of the task associated with it.
That's why the declared return type and the type given to the return
statement are different. The caller wants a Task<int>
but the continuation of the method wants an int
. The return
statement means "this method is done; give this value to my continuation" regardless of whether the method is synchronous or asynchronous.