[英]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.