我正在通过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();
}
}
我做错了什么让这个引发异常?为什么这只发生在我的班级?
答案 0 :(得分:1)
解决方案:在class A
之前添加public关键字。完美的工作。我知道它必须是非常简单的东西。
答案 1 :(得分:0)
首先 - 您不应该发出Box
操作码,因为A
是一个类,不需要装箱。拳击仅适用于价值类型。
第二 - 它失败的原因是因为该方法没有访问A类的权限(它不是公共的)。使A
public
或者您可以指示JIT编译器使用this constructor并将true
传递给skipVisibility参数来跳过可见性检查。
答案 2 :(得分:0)
问题很简单但不明显。首先,不要像已经指出的那样填充参数。但真正的问题是A类不公开。您正在使用的Invoke函数(而不是完整的)的默认绑定是仅查找公开方法。因为A是一个非公共类,这意味着它无法找到你的功能(我知道很惊人)并且失败了。