为什么用我自己的类的实例调用DynamicMethod会导致异常?

时间:2010-02-08 21:45:22

标签: c# .net reflection cil dynamicmethod

我正在通过Reflection.Emit在运行时创建自己的函数来学习CIL。我真的很惊讶直到现在已经很容易了,但是我遇到了一些我无法猜到的东西,我在文档中找不到任何相关内容。

我正在尝试创建一个简单打印我定义的非常简单的类的函数。如果我将我的代码更改为打印string,那么它可以工作,但是当我传递我的班级A的实例时,它总是无法运行。

奇怪的是,我可以注释掉我的函数体,但仍然失败了TargetInvocationException。它必须非常简单,但我看不到它是什么!

class A
{
    public override string  ToString()
    {
        return "AAA!";
    }
}

class Program
{
    static void Main(string[] args)
    {
        DynamicMethod func = new DynamicMethod("func", null, new Type[] { typeof(A) });

        ILGenerator il = func.GetILGenerator();

        //il.Emit(OpCodes.Ldarg_0);
        //il.Emit(OpCodes.Box, typeof(A));
        //il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(A) }));

        il.Emit(OpCodes.Ret);

        func.Invoke(null, new object[] { new A() });

        Console.Read();
    }
}

我做错了什么让这个引发异常?为什么这只发生在我的班级?

3 个答案:

答案 0 :(得分:1)

实际上这很傻。我花了几个小时的时间,但当我按照Laurent Etiemble的建议并创建了一个代表时,我告诉我我的A级不公开。

解决方案:在class A之前添加public关键字。完美的工作。我知道它必须是非常简单的东西。

答案 1 :(得分:0)

首先 - 您不应该发出Box操作码,因为A是一个类,不需要装箱。拳击仅适用于价值类型。

第二 - 它失败的原因是因为该方法没有访问A类的权限(它不是公共的)。使A public或者您可以指示JIT编译器使用this constructor并将true传递给skipVisibility参数来跳过可见性检查。

答案 2 :(得分:0)

问题很简单但不明显。首先,不要像已经指出的那样填充参数。但真正的问题是A类不公开。您正在使用的Invoke函数(而不是完整的)的默认绑定是仅查找公开方法。因为A是一个非公共类,这意味着它无法找到你的功能(我知道很惊人)并且失败了。