使用反射发射将现有对象加载到堆栈顶部

问题描述 投票:0回答:1

我正在尝试实现方法拦截,目前正在通过创建代理来实现,该代理将返回具有相同字段和属性的动态创建的对象。但是,该方法将被覆盖以执行类似的操作

  • 获取与该方法关联的所有属性,并基于这些属性执行一些代码(当前仅为Console.WriteLine
  • 执行实际方法
  • 根据原始属性执行其他代码。

到目前为止,我可以重写现有的虚拟方法并调用上述的Console.WriteLine,但是我无法调用实际的方法。

这是我到目前为止所拥有的

static void CreateMethod<T>(TypeBuilder tb)
        {
            var methodToOverride = typeof(T).GetMethod("Bar");
            var attribute = methodToOverride.GetCustomAttribute(typeof(MethodProxyAttribute));
            MethodBuilder methodBuilder = tb.DefineMethod(
                /* Change method name here */
                "Baz",
                MethodAttributes.Public
                | MethodAttributes.HideBySig
                | MethodAttributes.NewSlot
                | MethodAttributes.Virtual
                | MethodAttributes.Final,
                CallingConventions.HasThis,
                methodToOverride.ReturnType,
                Type.EmptyTypes
            );

            ILGenerator il = methodBuilder.GetILGenerator();

            il.Emit(OpCodes.Ldstr, "The I.M implementation of C");
            il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
            il.Emit(OpCodes.Ret);

            tb.DefineMethodOverride(methodBuilder, methodToOverride);
        }

我知道可以使用的解决方案

  • OpCode.NewObj创建对象的新实例并调用该方法。我不想使用它,因为它涉及在函数内部创建一个新对象,仅用于调用基本方法。
  • 使用带有静态字典作为V-Table的静态类来查找原始方法。

尽管有什么方法可以通过发出调用来调用原始方法?

c# reflection cil
1个回答
0
投票

结果是,可以使用现有的MethodInfo来调用基类方法。我通过添加这些行来做到这一点

© www.soinside.com 2019 - 2024. All rights reserved.