TResult>在任务&LT铸造TResult;到System.Object的 [英] Casting TResult in Task<TResult> to System.Object

查看:148
本文介绍了TResult>在任务&LT铸造TResult;到System.Object的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我加载的程序集,并呼吁这将创造型MyClass1的(这种类型是在运行时指定)通过反射使用MethodInfo.Invoke()一个新的对象的静态方法。这工作正常时,该方法是一种正常的同步方法。然而,被调用的方法是它返回任务℃的异步方法; MyClass1的>,将被用于检索使用task.Result结果

I am loading an assembly and calling a static method that will create a new object of type "MyClass1" (this type is specified at runtime) through reflection using MethodInfo.Invoke(). This works fine when the method is a normal sync method. However, the method being called is an async method which returns Task<MyClass1>, which will be used to retrieve the result using task.Result.

在理想情况下,我应该在任务使用MyClass1的作为TResult,但类型仅在运行时确定,所以我不能做到这一点。我正在寻找一种方式来获得任务和结果。我想投的TResult到System.Object的,并得到了类作为通用对象。以下是code我使用用于这一目的。

Ideally I should be using MyClass1 as TResult in the task, but the type is determined only at runtime so I can't do that. I am looking for a way to get the task and the result. I am trying to cast the TResult to System.Object and get the class as a generic Object. The following is the code I am using for this purpose.

public static void LoadAssembly()
{
    // Calling static async method directly works fine
    Task<MyClass1> task1 = MyClass1.MakeMyClass1();
    MyClass1 myClass1 = task1.Result;

    // Calling static async method through reflection through exception.
    Assembly assembly = Assembly.LoadFrom(dllName);
    Type type = assembly.GetType("AsyncDll.MyClass1");
    var types = assembly.GetTypes(); 
    MethodInfo[] methodInfos = types[0].GetMethods(BindingFlags.Public | BindingFlags.Static);
    Type myClassType = types[0];
    MethodInfo mi = myClassType.GetMethod("MakeMyClass1");
    Object obj = Activator.CreateInstance(mi.ReflectedType);
    Task<Object> task = (Task<Object>)mi.Invoke(obj, null); // Exception occurs here.
    Object result = task.Result;
}

以下是通过反射被调用的方法(试code)。这

Following is the method (test code) being called through reflection. This

public class MyClass1
{
    public static async Task<MyClass1> MakeMyClass1()
    {
        MyClass1 newObject = null;
        await Task.Run(() =>
        {
            newObject = new MyClass1();
        });
        return newObject;
    }
    ...
}

不幸的是,TResult的铸造是造成System.InvalidCastException

Unfortunately, the casting of TResult is causing System.InvalidCastException.

An unhandled exception of type 'System.InvalidCastException' occurred in Test.exe

Additional information: Unable to cast object of type 'System.Threading.Tasks.Task`1[MyClass1]' to type 'System.Threading.Tasks.Task`1[System.Object]'.

我怎么能投的TResult在任务&LT;>到通用对象,并使用task.Result得到的结果?我想AP preciate解决此问题的任何帮助。

How can I cast the TResult in Task<> to a generic object and get the result using task.Result? I would appreciate any help resolving this issue.

推荐答案

您不能施放任务&LT; T&GT; 任务&LT;对象&gt; ,因为任务&LT; T&GT; 不是<一个href=\"http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx\">covariant (这不是逆变,无论是)。最简单的解决办法是使用一些多个反射

You cannot cast Task<T> to Task<object>, because Task<T> is not covariant (it's not contravariant, either). The simplest solution would be to use some more reflection:

var task   = (Task) mi.Invoke (obj, null) ;
var result = task.GetType ().GetProperty ("Result").GetValue (task) ;

如果不经常执行该code这是缓慢和效率低下,而且可以使用。顺便说一句,什么是使用具有异步的 MakeMyClass1 方法,如果你要阻止等待它的结果?

This is slow and inefficient, but usable if this code is not executed often. As an aside, what is the use of having an asynchronous MakeMyClass1 method if you are going to block waiting for its result?

这篇关于TResult&gt;在任务&LT铸造TResult;到System.Object的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆