Consider the following case:
class A
{
public int Id;
}
class B : A
{
}
class Main
{
public async Task<int> Create(Type type)
{
MethodInfo method = this.GetType().GetMethod("Create", new Type[] { typeof(string) }).MakeGenericMethod(new Type[] { type });
A a = await (Task<A>)method.Invoke(this, new object[] { "humpf" });
return a.Id;
}
public async Task<T> Create<T>(string name) where T : A
{
T t = await Foo.Bar<T>(name);
return t;
}
}
Calling new Main().Create(typeof(B))
will fail with a
Unable to cast object of type '
System.Threading.Tasks.Task[B]
' to type 'System.Threading.Tasks.Task[A]
'
I don't quite understand because in this case, the Generic Create<T>
method can only return a Task<T>
where T
is always derived from 'A
', but maybe I'm missing an edge case here.
Besides that, how can I make this work? Thanks!
As per my comment:
Unlike interfaces, concrete types such as
Task<TResult>
cannot be covariant. See Why is Task not co-variant?. SoTask<B>
cannot be assigned to aTask<A>
.
The best solution I can think of is to use the underlying type Task
to perform the await
like so:
var task = (Task)method.Invoke(this, new object[] { "humpf" });
await task;
Then you can use reflection to get the value of the Result
:
var resultProperty = typeof(Task<>).MakeGenericType(type).GetProperty("Result");
A a = (A)resultProperty.GetValue(task);
return a.Id;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With