/// <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); }