簡體   English   中英

在非泛型方法中使用反射等待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[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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM