示例#1
0
        /// <summary>
        ///   C# allows this kind of scenarios:
        ///   interface I { void M (); }
        ///   class X { public void M (); }
        ///   class Y : X, I { }
        ///
        ///   For that case, we create an explicit implementation function
        ///   I.M in Y.
        /// </summary>
        void DefineProxy(Type iface, MethodInfo base_method, MethodInfo iface_method,
                         AParametersCollection param)
        {
            // TODO: Handle nested iface names
            string proxy_name = SimpleName.RemoveGenericArity(iface.FullName) + "." + iface_method.Name;

            MethodBuilder proxy = container.TypeBuilder.DefineMethod(
                proxy_name,
                MethodAttributes.HideBySig |
                MethodAttributes.NewSlot |
                MethodAttributes.CheckAccessOnOverride |
                MethodAttributes.Virtual,
                CallingConventions.Standard | CallingConventions.HasThis,
                base_method.ReturnType, param.GetEmitTypes());

#if GMCS_SOURCE
            Type[] gargs = iface_method.GetGenericArguments();
            if (gargs.Length > 0)
            {
                string[] gnames = new string[gargs.Length];
                for (int i = 0; i < gargs.Length; ++i)
                {
                    gnames[i] = gargs[i].Name;
                }

                proxy.DefineGenericParameters(gnames);
            }
#endif

            for (int i = 0; i < param.Count; i++)
            {
                string name = param.FixedParameters [i].Name;
                ParameterAttributes attr = Parameters.GetParameterAttribute(param.FixedParameters [i].ModFlags);
                proxy.DefineParameter(i + 1, attr, name);
            }

            int         top = param.Count;
            ILGenerator ig  = proxy.GetILGenerator();

            for (int i = 0; i <= top; i++)
            {
                ParameterReference.EmitLdArg(ig, i);
            }

            ig.Emit(OpCodes.Call, base_method);
            ig.Emit(OpCodes.Ret);

            container.TypeBuilder.DefineMethodOverride(proxy, iface_method);
        }