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) ;