c# - 我在 Reflection.Emit.DynamicMethod 中发出的 IL 有什么问题?

标签 c# .net reflection

理想情况下,我想使用 CreateObject 委托(delegate),因为生成这些动态方法的代码适用于应该能够处理任何类型(至少是基元、结构和类实例)的反序列化器.但是,我遇到了 CreateObject 委托(delegate)类型的问题,所以我决定尝试使用 CreateRectangle 委托(delegate)来调试。我离可行的解决方案更近了一点,但还有其他不对的地方。对于这两种情况,我的代码有什么问题?也就是说,如何使动态方法同时适用于 CreateObjectCreateRectangle?或者,我的调用代码是罪魁祸首吗?

输出:

{X=0,Y=0,Width=0,Height=0}

Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.

Exception has been thrown by the target of an invocation.
    Common Language Runtime detected an invalid program.

代码:

using System;
using System.Drawing;
using System.Reflection.Emit;

namespace Experiments {
    public class Program {
        private delegate object CreateObject();
        private delegate Rectangle CreateRectangle();

        static void Main() {
            Console.WriteLine(new Rectangle());
            Console.WriteLine();
            var dm = BuildDynamicMethod();
            TryCreateDelegate<CreateObject>(dm);
            Console.WriteLine();
            TryCreateDelegate<CreateRectangle>(dm);
            Console.WriteLine();
            Console.ReadKey();
        }

        private static void TryCreateDelegate<T>(DynamicMethod dm) {
            try {
                var co = dm.CreateDelegate(typeof (T));
                var value = co.DynamicInvoke(null);
                Console.WriteLine(value);
            } catch (Exception ex) {
                Console.WriteLine(ex.Message);
                var indent = 0;
                while (ex.InnerException != null) {
                    indent++;
                    ex = ex.InnerException;
                    Console.WriteLine(new string('\t', indent) + ex.Message);
                }
            }
        }

        private static DynamicMethod BuildDynamicMethod() {
            var tr = typeof(Rectangle);
            var dm = new DynamicMethod("buildNewRectangle", tr, Type.EmptyTypes);
            var il = dm.GetILGenerator();
            il.Emit(OpCodes.Ldloca_S, (byte)0);
            il.Emit(OpCodes.Initobj, tr);
            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Box, tr);
            il.Emit(OpCodes.Ret);
            return dm;
        }
    }
}

最佳答案

private delegate object CreateObject();
private delegate Rectangle CreateRectangle();

static void Main()
{
  Console.WriteLine(new Rectangle());
  Console.WriteLine();
  TryCreateDelegate<CreateObject>(BuildDynamicMethod_Boxed());
  Console.WriteLine();
  TryCreateDelegate<CreateRectangle>(BuildDynamicMethod());
  Console.WriteLine();
}

private static DynamicMethod BuildDynamicMethod_Boxed()
{
  var TRect = typeof(Rectangle);
  var dm = new DynamicMethod("buildNewRectangle", typeof(object), Type.EmptyTypes);
  var il = dm.GetILGenerator();
  il.Emit(OpCodes.Ldloca_S, il.DeclareLocal(TRect));
  il.Emit(OpCodes.Initobj, TRect);
  il.Emit(OpCodes.Ldloc_0);      
  il.Emit(OpCodes.Box, TRect);
  il.Emit(OpCodes.Ret);
  return dm;
}

private static DynamicMethod BuildDynamicMethod()
{
  var TRect = typeof(Rectangle);
  var dm = new DynamicMethod("buildNewRectangle", TRect, Type.EmptyTypes);
  var il = dm.GetILGenerator();
  il.Emit(OpCodes.Ldloca_S, il.DeclareLocal(TRect));
  il.Emit(OpCodes.Initobj, TRect);
  il.Emit(OpCodes.Ldloc_0);
  il.Emit(OpCodes.Ret);
  return dm;
}

private static void TryCreateDelegate<T>(DynamicMethod dm)
{
  try
  {
    var co = dm.CreateDelegate(typeof(T));
    var value = co.DynamicInvoke();
  }
  catch (Exception ex)
  {
    Console.WriteLine(ex.Message);
    var indent = 0;
    while (ex.InnerException != null)
    {
      indent++;
      ex = ex.InnerException;
      Console.WriteLine(new string('\t', indent) + ex.Message);
    }
  }
}

关于c# - 我在 Reflection.Emit.DynamicMethod 中发出的 IL 有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9660797/

相关文章:

c# - 将查询参数从强类型 View 传递回 Controller

c# - Web Api Controller 中无法识别 Json 方法

.net - RabbitMQ 消费者作为 Windows 服务

c# - 在 ASP.NET 5 中将声明与 OpenIdConnect.Server 结合使用

c# - 如何通过 Selenium 将 id 分配给元素

c# - 在 C# 中使用 Regex 提取 XML 值

.net - INFORMATION_SCHEMA 的 OleDb 等效项是什么

c# - 发出操作可能会破坏递增字段的运行时

c# - 将方法作为参数传递

c# - 使用反射的实际方法签名