コード例 #1
0
        /// <summary>
        /// Emits the dynamic method invoke binder.
        /// </summary>
        /// <param name="generator">The generator.</param>
        /// <param name="flag">The binding flags.</param>
        /// <param name="name">The name.</param>
        /// <param name="context">The context.</param>
        /// <param name="argInfo">The arg info.</param>
        /// <param name="argNames">The arg names.</param>
        public static void EmitDynamicMethodInvokeBinder(this ILGenerator generator, CSharpBinderFlags flag, string name, IEnumerable<Type> genericParms, Type context, ParameterInfo[] argInfo, IEnumerable<string> argNames)
        {
            if (genericParms != null && !genericParms.Any())
                genericParms = null;

            generator.Emit(OpCodes.Ldc_I4, (int)flag);
            generator.Emit(OpCodes.Ldstr, name);
            if (genericParms == null)
            {
                generator.Emit(OpCodes.Ldnull);
            }
            else
            {
                generator.EmitArray(typeof(Type), genericParms.Select(arg => (Action<ILGenerator>)(gen => gen.EmitTypeOf(arg))).ToList());
            }
            generator.EmitTypeOf(context);
            var tList = new List<Action<ILGenerator>> { gen => gen.EmitCreateCSharpArgumentInfo(CSharpArgumentInfoFlags.None) };

           

            tList.AddRange(argInfo.Zip(argNames,(p,n)=>new{p,n}).Select(arg => (Action<ILGenerator>)(gen =>
                                                                            {
                                                                                var tStart = CSharpArgumentInfoFlags.
                                                                                    UseCompileTimeType;

                                                                                if (arg.p.IsDefined(typeof(DynamicAttribute), true))
                                                                                {
                                                                                    tStart = CSharpArgumentInfoFlags.None;
                                                                                }

                                                                                if (arg.p.IsOut)
                                                                                {
                                                                                    tStart |=
                                                                                        CSharpArgumentInfoFlags.IsOut;
                                                                                }
                                                                                else if(arg.p.ParameterType.IsByRef)
                                                                                {
                                                                                    tStart |=
                                                                                       CSharpArgumentInfoFlags.IsRef;
                                                                                }

                                                                                if (!String.IsNullOrEmpty(arg.n))
                                                                                {
                                                                                    tStart |=
                                                                                     CSharpArgumentInfoFlags.NamedArgument;
                                                                                }

                                                                                gen.EmitCreateCSharpArgumentInfo(tStart, arg.n);
                                                                                return;
                                                                            })));
            generator.EmitArray(typeof(CSharpArgumentInfo), tList);
            generator.Emit(OpCodes.Call, typeof(Binder).GetMethod("InvokeMember", new[] { typeof(CSharpBinderFlags), typeof(string), typeof(IEnumerable<Type>), typeof(Type), typeof(CSharpArgumentInfo[]) }));
        }