繁体   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