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