Question

I use the following code for version tracking in a generated proxy:

ConstructorBuilder defaultConstructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);//typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);

var defaultConstructorIL = defaultConstructor.GetILGenerator();
defaultConstructorIL.Emit(OpCodes.Ldarg_0);
defaultConstructorIL.Emit(OpCodes.Call, type.GetConstructor(Type.EmptyTypes));
defaultConstructorIL.Emit(OpCodes.Ldarg_0);
defaultConstructorIL.Emit(OpCodes.Ldc_I4, 0);
defaultConstructorIL.Emit(OpCodes.Stfld, version);
defaultConstructorIL.Emit(OpCodes.Ldarg_0);
defaultConstructorIL.Emit(OpCodes.Call, typeof(DateTime).GetProperty("UtcNow", BindingFlags.Public | BindingFlags.Static).GetGetMethod());
defaultConstructorIL.Emit(OpCodes.Stfld, lastUpdate);
defaultConstructorIL.Emit(OpCodes.Ret);

version is a FieldBuilder of type "int". In this configuration, I can create an instance of the proxy type, and the proxy passes all of my unit tests.

If I change version to a field of type Int64, and modify the IL to:

defaultConstructorIL.Emit(OpCodes.Ldarg_0);
defaultConstructorIL.Emit(OpCodes.Ldc_I8, 0);
defaultConstructorIL.Emit(OpCodes.Stfld, version);

I get an invalid program exception when I try to instantiate an instance of the proxy type. Can someone shed some light as to why a change of type would cause this?

Was it helpful?

Solution

The problem is that you're using the overload of Emit() that takes an int, but ldc.i8 requires a long.

So, if you use the following line, your code will work fine (note the 0L literal instead of 0):

defaultConstructorIL.Emit(OpCodes.Ldc_I8, 0L);

OTHER TIPS

A detail found in the remarks section of http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldc_i4.aspx led me to:

defaultConstructorIL.Emit(OpCodes.Ldarg_0);
defaultConstructorIL.Emit(OpCodes.Ldc_I4_0, 0);
defaultConstructorIL.Emit(OpCodes.Conv_I8);
defaultConstructorIL.Emit(OpCodes.Stfld, version);

Which worked.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top