private static void EmitGetter(ILGenerator getGenerator, Type targetType, string propertyName) { var privateGetMethod = CompatTypeExtensions.GetMethod(targetType, "get_" + propertyName); if (privateGetMethod != null) { getGenerator.DeclareLocal(typeof(object)); //Load the first argument getGenerator.Emit(OpCodes.Ldarg_1); //Cast to the source type getGenerator.Emit(OpCodes.Castclass, targetType); //Get the property value getGenerator.EmitCall(OpCodes.Call, privateGetMethod, null); if (privateGetMethod.ReturnType.GetTypeInfo().IsValueType) { //Box getGenerator.Emit(OpCodes.Box, privateGetMethod.ReturnType); } //Store it // following IL seems unnecessary according to test results // original source contained the following 2 lines // getGenerator.Emit(OpCodes.Stloc_0); // getGenerator.Emit(OpCodes.Ldloc_0); } else { getGenerator.ThrowException(typeof(MissingMethodException)); } getGenerator.Emit(OpCodes.Ret); }
private static void EmitSetter(ILGenerator setGenerator, Type targetType, string propertyName) { var privateSetMethod = CompatTypeExtensions.GetMethod(targetType, "set_" + propertyName); if (privateSetMethod != null) { Type paramType = privateSetMethod.GetParameters()[0].ParameterType; setGenerator.DeclareLocal(paramType); //Load the first argument //(target object) setGenerator.Emit(OpCodes.Ldarg_1); //Cast to the source type setGenerator.Emit(OpCodes.Castclass, targetType); //Load the second argument setGenerator.Emit(OpCodes.Ldarg_2); //(value object) if (paramType.GetTypeInfo().IsValueType) { //Unbox it setGenerator.Emit(OpCodes.Unbox, paramType); //and load if (TypeOpCodeMapping.Map.TryGetValue(paramType, out var code)) { var load = code; setGenerator.Emit(load); } else { setGenerator.Emit(OpCodes.Ldobj, paramType); } } else { setGenerator.Emit(OpCodes.Castclass, paramType); //Cast class } setGenerator.EmitCall(OpCodes.Callvirt, privateSetMethod, null); //Set the property value } else { setGenerator.ThrowException(typeof(MissingMethodException)); } setGenerator.Emit(OpCodes.Ret); }