c# - 在非泛型方法中使用反射等待 Task<TDerived> 的结果

标签 c# generics reflection async-await

考虑以下情况:

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?. So Task<B> cannot be assigned to a 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;

关于c# - 在非泛型方法中使用反射等待 Task<TDerived> 的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34814878/

相关文章:

c# - 自定义验证属性未调用 ASP.NET MVC

java - 泛型内部类的问题

c# - 动态设置泛型类型参数

go - 如何获取函数参数的类型

c# - 使用转换器 WPF 绑定(bind)来自另一个 cs 文件的属性

c# - 是否可以在非异步方法中调用可等待方法?

使用不同运行时类型的通用容器

java - 从代理对象访问字段

c# - 找不到类型或命名空间 IAppBuilder(缺少使用指令 pr 程序集引用)

c# - 帮助定义泛型方法以及表达式树参数