考虑以下情况:
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))
将失败并显示
Unable to cast object of type '
System.Threading.Tasks.Task[B]
' to type 'System.Threading.Tasks.Task[A]
'
我不太明白,因为在这种情况下,通用 Create<T>
方法只能返回一个 Task<T>
其中 T
始终派生自“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
像这样:
var task = (Task)method.Invoke(this, new object[] { "humpf" });
await task;
然后你可以使用反射来获取Result
的值:
var resultProperty = typeof(Task<>).MakeGenericType(type).GetProperty("Result");
A a = (A)resultProperty.GetValue(task);
return a.Id;
关于c# - 在非泛型方法中使用反射等待 Task<TDerived> 的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34814878/