Reputation: 63835
So, I recently did some experimenting and discovered that it appears that Reflection.Emit doesn't support all of the opcodes in the ECMA spec. There are 3 opcodes missing:
ldelem.any
stelem.any
no.
(prefix)Are these opcodes just not supported in the Reflection API, or is there some way to generate them or something?
Upvotes: 8
Views: 773
Reputation: 7567
I placed a comment about this but the OpCode.Stelem
instruction at least in .net 4 translate sto a stelem.any
See it use to be the case that you had to encode the type you were storing in the array and for the primitives there was the various stelem.*
opcodes. If you were storing a reference type (something which declared as a delegate or a class) you would use stelem.Ref
and you would use Stelem (myType)
for value types (something which is declared as a struct or an enum).
However, with the advent of generics there came the type parameter and it could be anything it wanted. T
could be a reference type or it could be a value type. So stelem.any
is born to handle this unusual case. But you might say, I can only store an unboxed T into a T array so its entirely pointless, can't we just rely on the type of the array?
Well the array's type might also be generic, which would make things rather difficult. But more importantly its converse operation also helps verify the next operation.
ldarg.0
ldc.i4.0
ldelem.any !!T
Tells the verifier that the next instruction after this stack transition should be operated upon an unboxed T which is the generic methods parameter.
Upvotes: 0
Reputation: 3548
Actually, you can.
There is a wonderful walkthrough at http://msdn.microsoft.com/en-us/library/4xxf1410.aspx
Two essential parts are:
Create the generic parameters:
string[] typeParamNames = {"TFirst", "TSecond"};
GenericTypeParameterBuilder[] typeParams =
myType.DefineGenericParameters(typeParamNames);
GenericTypeParameterBuilder TFirst = typeParams[0];
GenericTypeParameterBuilder TSecond = typeParams[1];
Then create the method:
Type listOf = typeof(List<>);
Type listOfTFirst = listOf.MakeGenericType(TFirst);
Type[] mParamTypes = {TFirst.MakeArrayType()};
MethodBuilder exMethod =
myType.DefineMethod("ExampleMethod",
MethodAttributes.Public | MethodAttributes.Static,
listOfTFirst,
mParamTypes);
However, you should go through it entirely, as the generic parameters are used in so many different ways and sections (on the method, on the parameters, as result types, when invoking, ...).
-update- and if you want the .NET 2 specific version: http://msdn.microsoft.com/en-us/library/4xxf1410%28v=vs.80%29.aspx
The dropdown on the page lets you select many versions of the framework in which you can do it.
Upvotes: 1