![](/img/trans.png)
[英]Differentiating between generic and non-generic version of overloaded method using reflection
[英]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[B]
转换为'System.Threading.Tasks.Task[A]
'
我不太明白,因为在这种情况下,Generic Create<T>
方法只能返回一个Task<T>
,其中T
总是从' A
'派生,但也许我在这里缺少一个边缘情况。 除此之外,我怎样才能做到这一点? 谢谢!
根据我的评论:
与接口不同,
Task<TResult>
等具体类型不能协变。 请参阅为什么任务不是共变体? 。 因此无法将Task<B>
分配给Task<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;
上面的解决方案对我有帮助。 我对@Lukazoid解决方案进行了一些小调整......
var resultProperty = typeof(Task<>).MakeGenericType(type).GetProperty("Result");
A a = (A)resultProperty.GetValue(task);
至
dynamic a = task.GetType().GetProperty("Result")?.GetValue(task);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.