C# 正在尝试引用任务。继续(<;T>;来自Mono.Cecil 问题
我正试图严格使用C# 正在尝试引用任务。继续(<;T>;来自Mono.Cecil 问题,c#,generics,mono,cil,mono.cecil,C#,Generics,Mono,Cil,Mono.cecil,我正试图严格使用Mono.Cecil获取此IL指令。现在,我找到的唯一解决方案是导入每个引用程序集及其导出的类型,调用MakeGenericInstanceType(),以及Module.Import() 通缉令 它产生的代码是: call instance class [mscorlib]System.Threading.Tasks.Task`1<!!0> class [mscorlib]System.Threading.Tasks.Task`1<string>::Co
Mono.Cecil
获取此IL指令。现在,我找到的唯一解决方案是导入每个引用程序集及其导出的类型,调用MakeGenericInstanceType()
,以及Module.Import()
通缉令
它产生的代码是:
call instance class [mscorlib]System.Threading.Tasks.Task`1<!!0> class [mscorlib]System.Threading.Tasks.Task`1<string>::ContinueWith<class MyClass`1<valuetype [mscorlib]System.DateTime>>(class [mscorlib]System.Func`2<class [mscorlib]System.Threading.Tasks.Task`1<!0>, !!0>)
问题:明确定义的所有泛型:
=>!0
字符串
=>!!0
class MyClass`1
问题 你知道如何得到想要的指令,只使用引用吗 成功的(但非常黑客的)代码
getEverysingeType()
导入每个程序集,将其加载到内存中,并枚举其类型
不成功的代码(测试2)
var func=Module.Import(typeof(func)).MakeGenericType(taskType,returnType);
var continueWith=new-GenericInstanceMethod(new-MethodReference(“continueWith”,Module.Import(typeof(Task)).MakeGenericInstanceType(returnType),taskType){hassis=true});
continueWith.genericalarguments.Add(返回类型);
continueWith.Parameters.Add(新的参数定义(Module.Import(typeof(Func)).MakeGenericType(taskType,returnType)));
指令。创建(操作码。调用,继续);
有什么想法吗?在第二个示例中,您的
continueWith
中没有任何泛型参数,这就是结果方法引用不使用任何泛型参数的原因。您的目标方法签名使用两个,!0和!!0
。您必须保留泛型参数,并且返回/参数类型必须使用它们。从系统程序集导入内容似乎没有问题,请尝试以下方法:
var bf = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly ;
// import the *generic method* from the *generic type*
// can be done once per module
var cwgg = module.Import (typeof (Task<>).GetMethods (bf).Where (_ =>
_.Name == "ContinueWith" &&
_.IsGenericMethodDefinition &&
_.GetParameters ().Length == 1).Single ()) ;
// close Task<>, keep ContinueWith generic parameter open
var cwgi = new MethodReference (cwgg.Name, cwgg.ReturnType, taskType) ;
cwgi.HasThis = true ;
cwgi.GenericParameters.Add (new GenericParameter ("TNewResult", cwgi)) ;
cwgi.Parameters.Add (new ParameterDefinition (
cwgg.Parameters[0].ParameterType)) ;
// close ContinueWith
var continueWith = new GenericInstanceMethod (cwgi) ;
continueWith.GenericArguments.Add (returnType) ;
var bf=BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
//从*泛型类型导入*泛型方法**
//每个模块可以完成一次
var cwgg=module.Import(typeof(Task).GetMethods(bf).Where(=>
_.Name==“ContinueWith”&&
_.IsGenericMethodDefinition&&
_.GetParameters().Length==1.Single());
//关闭任务,在常规参数打开的情况下保持连续
var cwgi=新方法引用(cwgg.Name、cwgg.ReturnType、taskType);
cwgi.HasThis=true;
cwgi.GenericParameters.Add(新的GenericParameter(“TNewResult”,cwgi));
cwgi.Parameters.Add(新参数定义(
cwgg.Parameters[0].ParameterType));
//连续闭合
var continueWith=新的通用安装方法(cwgi);
continueWith.genericalarguments.Add(返回类型);
call instance class [mscorlib]System.Threading.Tasks.Task`1<class MyClass`1<valuetype [mscorlib]System.DateTime>> class [mscorlib]System.Threading.Tasks.Task`1<string>::ContinueWith<class MyClass`1<valuetype [mscorlib]System.DateTime>>(class [mscorlib]System.Func`2<class [mscorlib]System.Threading.Tasks.Task`1<string>, class MyClass`1<valuetype [mscorlib]System.DateTime>>)
var task = module.GetEverySingleType().First(...);
var returnType = module.GetEverySingleType().First(...);
var continueWith = module.Import((from m in task.GetMethods()
where m.Name == "ContinueWith"
let p = m.GetParameters()
where p.Length == 1 && p[0].ParameterType.Name == "Func`2"
select m.MakeGenericMethod(returnType)).First());
Instruction.Create(OpCodes.Call, continueWith);
var func = Module.Import(typeof(Func<,>)).MakeGenericType(taskType, returnType);
var continueWith = new GenericInstanceMethod(new MethodReference("ContinueWith", Module.Import(typeof(Task<>)).MakeGenericInstanceType(returnType), taskType) { HasThis = true });
continueWith.GenericArguments.Add(returnType);
continueWith.Parameters.Add(new ParameterDefinition(Module.Import(typeof(Func<,>)).MakeGenericType(taskType, returnType)));
Instruction.Create(OpCodes.Call, continueWith);
var bf = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly ;
// import the *generic method* from the *generic type*
// can be done once per module
var cwgg = module.Import (typeof (Task<>).GetMethods (bf).Where (_ =>
_.Name == "ContinueWith" &&
_.IsGenericMethodDefinition &&
_.GetParameters ().Length == 1).Single ()) ;
// close Task<>, keep ContinueWith generic parameter open
var cwgi = new MethodReference (cwgg.Name, cwgg.ReturnType, taskType) ;
cwgi.HasThis = true ;
cwgi.GenericParameters.Add (new GenericParameter ("TNewResult", cwgi)) ;
cwgi.Parameters.Add (new ParameterDefinition (
cwgg.Parameters[0].ParameterType)) ;
// close ContinueWith
var continueWith = new GenericInstanceMethod (cwgi) ;
continueWith.GenericArguments.Add (returnType) ;