【问题标题】:how to make reference to a GenericInstanceMethod on a GenericInstanceType in mono cecil如何在 Mono cecil 中引用 GenericInstanceType 上的 GenericInstanceMethod
【发布时间】:2018-06-09 03:24:15
【问题描述】:

我要引用的方法定义如下:

class Foo<T1> {
    void Bar<T2>(int value) {...}
}

我的问题与具有通用参数的 Foo 和 Bar 有关 如果我使用

static public GenericInstanceMethod MakeGenericMethod(this MethodReference method, TypeReference[] genericArguments)
{
    var _method = new GenericInstanceMethod(method);
    foreach (var _argument in genericArguments) {
        _method.GenericArguments.Add(genericArguments);
    }
    return _method;
}

生成的代码会有一个引用

Foo<>.Bar<T2>(int)

如果我使用

static public MethodReference Reference(this GenericInstanceType genericInstanceType, MethodReference method)
    _methodReference = new MethodReference(method.Name, _returnType, genericInstanceType) {
        HasThis = method.HasThis,
        ExplicitThis = method.ExplicitThis,
        CallingConvention = method.CallingConvention
    };
    foreach (var parameter in method.Parameters) {
        _methodReference.Parameters.Add(parameter);
    }
    return _methodReference;  
}

生成的代码会有一个引用

Foo<T1>.Bar(int);

两者都是我所期望的,但不是我想要的,我找不到将它们组合起来以产生正确值的方法

【问题讨论】:

    标签: mono.cecil


    【解决方案1】:

    您需要从方法引用中创建一个通用实例方法:

    using System;
    using System.Linq;
    using Mono.Cecil;
    using Mono.Cecil.Cil;
    using TypeAttributes = Mono.Cecil.TypeAttributes;
    
    namespace TestGenericMethod
    {
        public class Foo<T>
        {
            public void M<X>(X x)
            {
                Console.WriteLine(x);
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                if (args.Length > 0)
                {
                    var p = new Program();
                    p.Test(args[0]);
                    return;
                }
    
                var a = AssemblyDefinition.ReadAssembly(typeof(Program).Assembly.Location);
    
                var tr = a.MainModule.ImportReference(typeof(Foo<int>));
    
                var tm = a.MainModule.Types.SingleOrDefault(t => t.Name == "Program").Methods.SingleOrDefault(m => m.Name == "Test");
    
                var gm = new MethodReference("M", a.MainModule.TypeSystem.Void, tr);
                var genericParameter = new GenericParameter("X", gm);
                gm.GenericParameters.Add(genericParameter);
                gm.Parameters.Add(new ParameterDefinition(genericParameter));
                gm.HasThis = true;
                var mmm = new GenericInstanceMethod(gm);
                mmm.GenericArguments.Add(a.MainModule.TypeSystem.String);
    
                Console.WriteLine(gm.GetType().FullName);
    
                var il = tm.Body.GetILProcessor();
    
                var ret = il.Body.Instructions.SingleOrDefault(i => i.OpCode == OpCodes.Ret);
    
                il.InsertBefore(ret, il.Create(OpCodes.Ldloc_0));
                il.InsertBefore(ret, il.Create(OpCodes.Ldarg_1));
                il.InsertBefore(ret, il.Create(OpCodes.Callvirt, mmm));
    
                a.Write("Output.exe");
            }
    
            private void Test(string s)
            {
                var o = new Foo<int>();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-12
      • 2021-07-05
      • 2021-06-20
      • 2012-06-19
      • 2021-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多