Why can't it figure out that my method returns an Task of IList<int>
?
Because it doesn't. In this call:
Task.FromResult(new List<int>());
... type inference makes that equivalent to:
Task.FromResult<List<int>>(new List<int>());
So your method is trying to return a Task<List<int>>
- and that's not compatible with Task<IList<int>>
.
To simplify the point about Task<>
, let's use string
and object
instead, and take out type inference and async entirely. The following code does not compile, and indeed shouldn't:
Task<string> stringTask = Task.FromResult<string>("text");
Task<object> objectTask = stringTask; // Doesn't compile
Task<T>
is invariant - there's no conversion from Task<T1>
to Task<T2>
just because there's a conversion from T1
to T2
.
You don't need an explicit cast though - you can just use the implicit conversion earlier:
public Task<IList<int>> TestAsync()
{
// It's important that this variable is explicitly typed as IList<int>
IList<int> result = new List<int>();
return Task.FromResult(result);
}
This uses the implicit conversion from List<int>
to IList<int>
for the result
variable, and then it calls Task.FromResult<IList<int>>
using type inference.
An alternative is to keep the method as it was before, except you specify the type argument for Task.FromResult
:
public Task<IList<int>> TestAsync()
{
return Task.FromResult<IList<int>>(new List<int>());
}
>` is not a `Task>`.
– Lee Jul 30 '18 at 16:59