首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在mono cecil中引用GenericInstanceType上的GenericInstanceMethod

如何在mono cecil中引用GenericInstanceType上的GenericInstanceMethod
EN

Stack Overflow用户
提问于 2018-04-14 23:33:03
回答 1查看 395关注 0票数 1

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

代码语言:javascript
复制
class Foo<T1> {
    void Bar<T2>(int value) {...}
}

我的问题是连接到Foo和Bar,如果我使用

代码语言:javascript
复制
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;
}

生成的代码将引用

代码语言:javascript
复制
Foo<>.Bar<T2>(int)

如果我使用

代码语言:javascript
复制
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;  
}

生成的代码将引用

代码语言:javascript
复制
Foo<T1>.Bar(int);

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

EN

回答 1

Stack Overflow用户

发布于 2018-06-09 03:07:14

您需要在方法引用之外创建一个泛型实例方法:

代码语言:javascript
复制
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>();
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49833118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档