C# 转换任务<;对象>;任务<;T>;其中T未知

C# 转换任务<;对象>;任务<;T>;其中T未知,c#,generics,dynamic,task,C#,Generics,Dynamic,Task,如何将Task转换为Task,其中T未知 比如说 任务到任务 接口IAsyncations { 任务GetValueAsync(); } 类代理:RealProxy { 公共代理():基(typeof(iasyncations)){} 公共覆盖IMessage调用(IMessage msg) { var call=(IMethodCallMessage)消息; var method=(MethodInfo)call.MethodBase; if(method.ReturnType.IsSubcl

如何将
Task
转换为
Task
,其中T未知

比如说
任务到任务

接口IAsyncations
{
任务GetValueAsync();
}
类代理:RealProxy
{
公共代理():基(typeof(iasyncations)){}
公共覆盖IMessage调用(IMessage msg)
{
var call=(IMethodCallMessage)消息;
var method=(MethodInfo)call.MethodBase;
if(method.ReturnType.IsSubclassOf(typeof(Task)))
{
//返回类型为任务
Task taskResult=AsyncMethod2(调用);
返回新的ReturnMessage(taskResult,null,0,call.LogicalCallContext,call);//如果taskResult不是任务,则返回InvalidCastException
}
其他的
{
// ...
返回null;
}
}
静态void Main()
{
Proxy p=新代理();
IAsyncations tProxy=(IAsyncations)p.GetTransparentProxy();
int result=tProxy.GetValueAsync().result;//InvalidCastException
}
//这种方法效果很好
任务异步方法(IMethodCallMessage调用)
{
Task Task=Task.FromResult(1234);
返回任务;
}
//这种方法行不通
任务AsyncMethod2(IMethodCallMessage调用)
{
类型taskReturnType=((MethodInfo)call.MethodBase).ReturnType;//任务
任务结果=Task.FromResult(1234);
//将结果转换为taskReturnType
// ...
//
返回结果;
}
}
我找到了一个解决方案,但它非常昂贵:

Task AsyncMethod2(IMethodCallMessage call, MethodInfo method)
{
    PropertyInfo resultProp = method.ReturnType.GetProperty("Result");
    Type taskResultType = resultProp.PropertyType;
    Type tcs = typeof(TaskCompletionSource<>);
    Type[] typeArgs = { taskResultType };
    Type genericTcs = tcs.MakeGenericType(typeArgs);
    var taskProperty = genericTcs.GetProperty("Task");
    object tcsInstance = Activator.CreateInstance(genericTcs);
    MethodInfo setResult = genericTcs.GetMethod("SetResult");
    MethodInfo setException = genericTcs.GetMethod("SetException", new Type[] { typeof(IEnumerable<Exception>)});
    var setEx = (Action< IEnumerable<Exception>>)setException.CreateDelegate(typeof(Action<IEnumerable<Exception>>), tcsInstance);
    Task task = (Task)taskProperty.GetValue(tcsInstance);

    Task<object> result = new Task<object>(delegate 
    {
        //throw new InvalidOperationException("qwerty");
        return 1234;
    });

    result.Start();

    result.ContinueWith(x =>
    {
        var args = new object[] { x.Result };
        setResult.Invoke(tcsInstance, args);
    }, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion);

    result.ContinueWith(x =>
    {
        setEx(x.Exception.InnerExceptions);
    }, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnFaulted);

    return task;
}
任务AsyncMethod2(IMethodCallMessage调用,MethodInfo方法)
{
PropertyInfo resultProp=method.ReturnType.GetProperty(“结果”);
类型taskResultType=ResultPropertyType;
类型tcs=类型of(TaskCompletionSource);
Type[]typeArgs={taskResultType};
Type genericts=tcs.MakeGenericType(typeArgs);
var taskProperty=genericts.GetProperty(“任务”);
对象tcsInstance=Activator.CreateInstance(genericTcs);
MethodInfo setResult=genericts.GetMethod(“setResult”);
MethodInfo setException=genericts.GetMethod(“setException”,新类型[]{typeof(IEnumerable)});
var setEx=(Action)setException.CreateDelegate(typeof(Action),tcsInstance);
Task Task=(Task)taskProperty.GetValue(tcs实例);
任务结果=新任务(委托
{
//抛出新的无效操作异常(“qwerty”);
返回1234;
});
result.Start();
结果。继续(x=>
{
var args=新对象[]{x.Result};
调用(tcsInstance,args);
},TaskContinuationOptions.Executes同步执行| TaskContinuationOptions.OnlyOnRanToCompletion);
结果。继续(x=>
{
setEx(x.Exception.InnerExceptions);
},TaskContinuationOptions.Executes同步执行| TaskContinuationOptions.OnlyOnFaulted);
返回任务;
}
创建此方法:

public async static Task<T> Convert<T>(Task<object> task)
{
    var result = await task;

    return (T) result;
}
公共异步静态任务转换(任务任务)
{
var结果=等待任务;
返回(T)结果;
}
然后您可以这样做(这是必需的,因为T只在运行时已知):

//假设变量“task”引用任务
类型taskReturnType=((MethodInfo)call.MethodBase)//e、 g.任务
var type=taskReturnType.GetGenericArguments()[0]//获取结果类型,例如int
var convert_method=this.GetType().GetMethod(“convert”).MakeGenericMethod(类型)//获取Convert方法的封闭版本,例如Convert
var result=convert_method.Invoke(null,新对象[]{task})//调用convert方法并返回泛型任务,例如Task

关键是代码必须异步执行,这就是为什么在任务未完成时我没有1234值的原因。我几乎可以肯定(Unity异步拦截器)包含您要查找的确切代码。这有点难以理解,但这确实是我要找的,谢谢此des不适合我。我得到一个异常,无法将
任务
转换为
任务
。使用这个方法作为灵感,我创建了一个新方法:
publicstatictaskconvert(T值){returntask.FromResult((T)值);}
public async static Task<T> Convert<T>(Task<object> task)
{
    var result = await task;

    return (T) result;
}
//Assuming that variable "task" is referencing the Task<object>

Type taskReturnType = ((MethodInfo) call.MethodBase).ReturnType; //e.g. Task<int>

var type = taskReturnType.GetGenericArguments()[0]; //get the result type, e.g. int

var convert_method = this.GetType().GetMethod("Convert").MakeGenericMethod(type); //Get the closed version of the Convert method, e.g. Convert<int>

var result = convert_method.Invoke(null, new object[] {task}); //Call the convert method and return the generic Task, e.g. Task<int>