/// <summary> /// Emit parameter IL for a method call. /// </summary> /// <param name="il">IL generator.</param> /// <param name="argumentTypes">Arguments type defined for a the constructor.</param> private void EmitArgsIL(ILGenerator il, Type[] argumentTypes) { // Add args. Since all args are objects, value types are unboxed. // Refs to value types are to be converted to values themselves. for (int i = 0; i < argumentTypes.Length; i++) { // Push args array reference on the stack , followed by the index. // Ldelem will resolve them to args[i]. il.Emit(OpCodes.Ldarg_1); // Argument 1 is argument array. il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldelem_Ref); // If param is a primitive/value type then we need to unbox it. Type paramType = argumentTypes[i]; if (paramType.IsValueType) { if (paramType.IsPrimitive || paramType.IsEnum) { il.Emit(OpCodes.Unbox, paramType); il.Emit(BoxingOpCodes.GetOpCode(paramType)); } else if (paramType.IsValueType) { il.Emit(OpCodes.Unbox, paramType); il.Emit(OpCodes.Ldobj, paramType); } } } }
private void EmitArgsIL(ILGenerator il, Type[] argumentTypes) { for (int i = 0; i < argumentTypes.Length; i++) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldelem_Ref); Type cls = argumentTypes[i]; if (cls.IsValueType) { if (cls.IsPrimitive || cls.IsEnum) { il.Emit(OpCodes.Unbox, cls); il.Emit(BoxingOpCodes.GetOpCode(cls)); } else if (cls.IsValueType) { il.Emit(OpCodes.Unbox, cls); il.Emit(OpCodes.Ldobj, cls); } } } }