等待Task< TDerived>的结果.在非泛型方法中使用反射 [英] Await the result of Task<TDerived> using reflection in a non-generic method
问题描述
请考虑以下情况:
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;
}
}
呼叫new Main().Create(typeof(B))
将失败,并显示
无法将类型为"
System.Threading.Tasks.Task[B]
"的对象强制转换为 输入"System.Threading.Tasks.Task[A]
"
Unable to cast object of type '
System.Threading.Tasks.Task[B]
' to type 'System.Threading.Tasks.Task[A]
'
我不太了解,因为在这种情况下,通用Create<T>
方法只能返回Task<T>
,其中T
始终是从'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!
推荐答案
根据我的评论:
与接口不同,
Task<TResult>
之类的具体类型不能协变.请参阅为什么Task不是协变的?.因此无法将Task<B>
分配给Task<A>
.
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>
.
我能想到的最好的解决方案是使用基础类型Task
来执行await
,如下所示:
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;
然后您可以使用反射来获取Result
的值:
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;
这篇关于等待Task< TDerived>的结果.在非泛型方法中使用反射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!