2

我通过在运行时使用Reflection.Emit. 实际上,我很惊讶到目前为止事情有多容易,但是我遇到了一些我无法猜测的事情,而且我在文档中找不到任何相关的东西。

我正在尝试创建一个简单地打印我定义的非常简单的类的函数。例如,如果我将代码更改为 print string,它可以工作,但是当我传递我的 class 的实例时它总是无法运行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();
    }
}

我做错了什么使这个引发异常?为什么这只发生在我的课程中?

4

3 回答 3

1

实际上这很愚蠢。我在这上面花了几个小时,但是当我听从 Laurent Etiemble 的建议并创建了一个代表时,我得到一个例外,告诉我我的 A 类不公开。

解决方法:在前面加上public关键字class A。完美运行。我知道这一定是非常简单的事情。

于 2010-02-08T22:31:01.227 回答
0

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

其次 - 它失败的原因是因为该方法没有访问 A 类的权限(它不是公共的)。make OR 您可以通过使用此构造函数并传递给 skipVisibility 参数A public来指示 JIT 编译器跳过可见性检查。true

于 2010-02-08T22:18:19.480 回答
0

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

于 2010-02-08T22:31:28.370 回答