예제 #1
0
        private static void GenerateInvokeMethodIl(MethodDefinition method,
                                                   Type[] paramTypes,
                                                   ParameterInfo[] parameters,
                                                   MethodInfo proxyOnGetMethod)
        {
            var il = method.GetILGenerator();
            var argsLocal = il.DeclareLocal(typeof(object[]));

            il.Emit(OpCodes.Ldc_I4, paramTypes.Length);
            il.Emit(OpCodes.Newarr, typeof(object));
            il.Emit(OpCodes.Stloc, argsLocal);

            foreach (var param in parameters)
            {
                il.Emit(OpCodes.Ldloc, argsLocal);
                il.Emit(OpCodes.Ldc_I4, param.Position);
                il.Emit(OpCodes.Ldarg, param.Position + 1); // +1 since Ldarg0 means this
                if (param.ParameterType.IsValueType)
                    il.Emit(OpCodes.Box, param.ParameterType);
                il.Emit(OpCodes.Stelem_Ref);
            }

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetCurrentMethod"));
            il.Emit(OpCodes.Castclass, typeof(MethodInfo));
            //il.Emit(OpCodes.Ldstr, targetMethod.Name);
            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Callvirt, proxyOnGetMethod);

            if (method.ReturnType == typeof(void))
                il.Emit(OpCodes.Pop);
            else if (method.ReturnType.IsValueType)
                il.Emit(OpCodes.Unbox_Any, method.ReturnType);
            else if (method.ReturnType != typeof(object))
                il.Emit(OpCodes.Castclass, method.ReturnType);

            il.Emit(OpCodes.Ret);
        }
예제 #2
0
 private static bool BaseTypeHasMatchingPublicMethod(Type baseDef, MethodInfo targetMethod)
 {
     return baseDef.GetMethods()
                   .Any(
                       x =>
                       x.Name == targetMethod.Name &&
                       x.ReturnType == targetMethod.ReturnType &&
                       x.GetParameters()
                        .Select(y => y.ParameterType)
                        .SequenceEqual(targetMethod.GetParameters().Select(y => y.ParameterType)));
 }
예제 #3
0
        private static void CopyGenericMethodParameters(MethodInfo targetMethod,
                                                        MethodDefinition method,
                                                        Dictionary<Type, Type> genArgMapping,
                                                        Func<Type, Type> typeReplacer)
        {
            if (targetMethod.IsGenericMethodDefinition)
            {
                var targetGenArgs = targetMethod.GetGenericArguments();

                var items =
                    method.DefineGenericParameters(targetGenArgs.Select(x => x.Name).ToArray()).Zip(targetGenArgs,
                                                                                                    (paramBuilder,
                                                                                                     target) =>
                                                                                                        new
                                                                                                        {
                                                                                                            paramBuilder,
                                                                                                            target
                                                                                                        })
                          .ToList();
                foreach (var arg in items)
                {
                    arg.paramBuilder.SetGenericParameterAttributes(arg.target.GenericParameterAttributes);
                    genArgMapping[arg.target] = arg.paramBuilder;
                }
                foreach (var arg in items)
                {
                    IEnumerable<Type> interfaceConstraints =
                        arg.target.GetGenericParameterConstraints().Select(typeReplacer).ToList();
                    if (arg.target.BaseType != null)
                    {
                        var baseTypeFixed = typeReplacer(arg.target.BaseType);
                        if (!baseTypeFixed.IsInterface)
                            arg.paramBuilder.SetBaseTypeConstraint(baseTypeFixed);
                        else
                        {
                            //arg.paramBuilder.SetBaseTypeConstraint(typeof(object));
                            interfaceConstraints = interfaceConstraints.Append(baseTypeFixed);
                        }
                        //if (arg.target.BaseType.IsGenericParameter)
                        //{
                        //    interfaceConstraints = interfaceConstraints.Except(arg.target.BaseType.GetInterfaces());
                        //}
                    }
                    arg.paramBuilder.SetInterfaceConstraints(interfaceConstraints.ToArray());
                }
            }
        }