Reputation: 5241
I have the following generic and non-generic methods:
public async Task<T> LoadAsync(Guid id)
{
return await _someService.SomeMethodAsync(id);
}
async Task<object> LoadObjectAsync(Guid id) => await LoadAsync(id);
Trying to follow the advice from Stephen Cleary, I thought I'd make the code more efficient by removing the async/await from the LoadObjectAsync
method as it is a passthrough. However, when I change the signature to:
Task<object> LoadObjectAsync(Guid id) => LoadAsync(id);
I get an error saying I cannot implicitly convert from Task<T>
to Task<object>
. What I'd like to know is how the async await avoids this conversion issue? I know that generic variance prohibits the conversion of the Task<>
but why does this not apply to the async/await version?
Upvotes: 1
Views: 235
Reputation: 456507
Trying to follow the advice from Stephen Cleary
The advice in that article is "leave the async
/await
in there unless you need to remove it". In this case, the method looks like a passthrough but is actually doing an implicit cast.
What I'd like to know is why the async await avoids this conversion issue?
With async
and await
, the code is casting T
to object
, which is always allowed.
Without async
and await
, the code is casting Task<T>
to Task<object>
, which is not allowed. This is because classes cannot support generic variance, and there is no ITask<T>
type.
Upvotes: 5