/// <summary> /// Builds the type initializer. /// </summary> /// <param name="typeBuilder">The type builder.</param> /// <param name="methodInfo">The method information.</param> /// <param name="genericParameterTypes">The generic parameter types.</param> /// <param name="methodFieldInfo">The method information static field information.</param> private static void BuildTypeInitializer(TypeBuilder typeBuilder, MethodInfo methodInfo, Type[] genericParameterTypes, FieldInfo methodFieldInfo) { // Define type initializer. var typeInitializer = typeBuilder.DefineConstructor( MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.SpecialName, CallingConventions.Standard, null); // Implement type initializer. var ilGenerator = typeInitializer.GetILGenerator(); // Get and load target method information. var targetMethodInfo = methodInfo.MapGenericMethod(genericParameterTypes); var declaringType = targetMethodInfo.DeclaringType; ilGenerator.Emit(OpCodes.Ldtoken, targetMethodInfo); ilGenerator.Emit(OpCodes.Ldtoken, declaringType); ilGenerator.EmitCall(MethodBaseGetMethodFromHandleMethodInfo); // Store method information. ilGenerator.Emit(OpCodes.Castclass, typeof (MethodInfo)); ilGenerator.Emit(OpCodes.Stsfld, methodFieldInfo); ilGenerator.Emit(OpCodes.Ret); }
/// <summary> /// Builds the invoke method. /// </summary> /// <param name="typeBuilder">The type builder.</param> /// <param name="methodInfo">The method information.</param> /// <param name="genericParameterTypes">The generic parameter types.</param> /// <param name="isVirtual">A value indicating whether the method should be called virtually.</param> private static void BuildInvokeMethod(TypeBuilder typeBuilder, MethodInfo methodInfo, Type[] genericParameterTypes, bool isVirtual) { var invokeMethodInfo = isVirtual ? MethodInfoBaseInvokeVirtualMethodInfo : MethodInfoBaseInvokeBaseMethodInfo; // Define method. var methodBuilder = typeBuilder.DefineMethod(invokeMethodInfo, false, true); methodBuilder.DefineParameters(invokeMethodInfo); // Implement method. var ilGenerator = methodBuilder.GetILGenerator(); // Load target object. ilGenerator.Emit(OpCodes.Ldarg_1); // Load parameter values. var parameterTypes = methodInfo.MapGenericParameterTypes(genericParameterTypes); var parameterValueLocalBuilders = new LocalBuilder[parameterTypes.Length]; LoadParameterValues(ilGenerator, 2, parameterTypes, parameterValueLocalBuilders); // Call target method. var targetMethodInfo = methodInfo.MapGenericMethod(genericParameterTypes); ilGenerator.Emit(isVirtual ? OpCodes.Callvirt : OpCodes.Call, targetMethodInfo); // Restore by reference parameter values. RestoreByReferenceParameterValues(ilGenerator, 2, parameterTypes, parameterValueLocalBuilders); // Handle return value. var returnType = methodInfo.MapGenericReturnType(genericParameterTypes); if (returnType.IsVoid()) ilGenerator.Emit(OpCodes.Ldnull); else ilGenerator.EmitBox(returnType); ilGenerator.Emit(OpCodes.Ret); }