所以,我最近做了一些实验,发现似乎Reflection.Emit不支持ECMA规范中的所有操作码。缺少3个操作码:
ldelem.any
stelem.any
no.
(前缀)这些操作码是否在Reflection API中不受支持,或者是否有某种方法可以生成它们?
答案 0 :(得分:1)
实际上,你可以。
http://msdn.microsoft.com/en-us/library/4xxf1410.aspx
有一个精彩的演练两个基本部分是:
创建通用参数:
string[] typeParamNames = {"TFirst", "TSecond"};
GenericTypeParameterBuilder[] typeParams =
myType.DefineGenericParameters(typeParamNames);
GenericTypeParameterBuilder TFirst = typeParams[0];
GenericTypeParameterBuilder TSecond = typeParams[1];
然后创建方法:
Type listOf = typeof(List<>);
Type listOfTFirst = listOf.MakeGenericType(TFirst);
Type[] mParamTypes = {TFirst.MakeArrayType()};
MethodBuilder exMethod =
myType.DefineMethod("ExampleMethod",
MethodAttributes.Public | MethodAttributes.Static,
listOfTFirst,
mParamTypes);
但是,你应该完全通过它,因为泛型参数在很多不同的方式和部分中使用(在方法,参数,结果类型,调用时......)。
-update-如果你想要.NET 2特定版本:http://msdn.microsoft.com/en-us/library/4xxf1410%28v=vs.80%29.aspx
页面上的下拉菜单允许您选择框架的许多版本。
答案 1 :(得分:0)
我对此发表了评论,但至少在.net 4中的OpCode.Stelem
指示转换为stelem.any
请参阅使用情况,您必须对存储在数组中的类型进行编码,对于基元,有各种stelem.*
操作码。如果您正在存储引用类型(声明为委托或类的东西),您将使用stelem.Ref
并且您将Stelem (myType)
用于值类型(被声明为结构或枚举的东西)
然而,随着泛型的出现,出现了类型参数,它可能是它想要的任何东西。 T
可以是引用类型,也可以是值类型。所以stelem.any
诞生于处理这种不寻常的情况。但你可能会说,我只能将一个未装箱的T存储到一个T阵列中,所以它完全没有意义,我们只能依靠阵列的类型吗?
阵列的类型也可能是通用的,这会让事情变得相当困难。但更重要的是,它的逆向操作也有助于验证下一步操作。
ldarg.0
ldc.i4.0
ldelem.any !!T
告诉验证者应该在未装箱的T(通用方法参数)上操作此堆栈转换之后的下一条指令。