コード例 #1
0
ファイル: MethodSwitcher.cs プロジェクト: huoxudong125/Cyjb
        /// <summary>
        /// 返回 <paramref name="type"/> 中与指定标识符相关的静态方法切换器。
        /// 多次获取特定类型中同一标识符的方法切换器,必须使用相同的
        /// <typeparamref name="TDelegate"/> 和 <paramref name="index"/>。
        /// </summary>
        /// <typeparam name="TDelegate">使用基类型调用方法的委托。</typeparam>
        /// <param name="type">在其中查找静态方法的类型。</param>
        /// <param name="index">方法的关键参数索引。</param>
        /// <param name="id">方法切换器的标识符。</param>
        /// <returns><paramref name="type"/> 中与指定标识符相关的静态方法切换器。</returns>
        public static TDelegate GetSwitcher <TDelegate>(Type type, int index, string id)
            where TDelegate : class
        {
            ExceptionHelper.CheckArgumentNull(type, "type");
            Type dlgType = typeof(TDelegate);

            ExceptionHelper.CheckDelegateType(dlgType, "TDelegate");
            Dictionary <Type, Delegate> methods = GetMethods <TDelegate>(type, id, index, true);
            MethodInfo invoke = dlgType.GetMethod("Invoke");

            // 构造委托。
            ParameterExpression[] paramList = invoke.GetParameters().ToExpressions();
            // 取得关键类型。
            Expression getType = Expression.Call(paramList[index], typeof(object).GetMethod("GetType"));
            // 从字典取得相应委托。
            Expression getDlg = Expression.Invoke(
                Expression.Constant((Func <Dictionary <Type, Delegate>, Type, Delegate>)GetMethod),
                Expression.Constant(methods), getType);

            getDlg = Expression.Convert(getDlg, dlgType);
            // 调用委托。
            Expression invokeDlg = Expression.Invoke(getDlg, paramList);

            return(Expression.Lambda <TDelegate>(invokeDlg, paramList).Compile() as TDelegate);
        }
コード例 #2
0
ファイル: MethodSwitcher.cs プロジェクト: huoxudong125/Cyjb
        /// <summary>
        /// 返回指定对象中与指定标识符相关的实例方法切换器。
        /// 多次获取特定类型中同一标识符的方法切换器,必须使用相同的
        /// <typeparamref name="TDelegate"/> 和 <paramref name="index"/>。
        /// </summary>
        /// <typeparam name="TDelegate">使用基类型调用方法的委托。</typeparam>
        /// <param name="target">实例方法的目标对象。</param>
        /// <param name="index">方法的关键参数索引。</param>
        /// <param name="id">方法切换器的标识符。</param>
        /// <returns>指定对象中与指定标识符相关的实例方法切换器。</returns>
        public static TDelegate GetSwitcher <TDelegate>(object target, int index, string id)
            where TDelegate : class
        {
            ExceptionHelper.CheckArgumentNull(target, "target");
            Type dlgType = typeof(TDelegate);

            ExceptionHelper.CheckDelegateType(dlgType, "TDelegate");
            Dictionary <Type, Delegate> methods = GetMethods <TDelegate>(target.GetType(), id, index, false);
            MethodInfo invoke = dlgType.GetMethod("Invoke");

            // 构造委托。
            ParameterExpression[] paramList = invoke.GetParameters().ToExpressions();
            // 取得关键类型。
            Expression getType = Expression.Call(paramList[index], typeof(object).GetMethod("GetType"));
            // 从字典取得相应委托。
            Expression getDlg = Expression.Invoke(
                Expression.Constant((Func <Dictionary <Type, Delegate>, Type, Delegate>)GetMethod),
                Expression.Constant(methods), getType);
            // 调用实例方法委托。
            Type insDlgType = GetInstanceDlgType(dlgType);

            getDlg = Expression.Convert(getDlg, insDlgType);
            Expression[] invokeArgs = new Expression[paramList.Length + 1];
            invokeArgs[0] = Expression.Constant(target);
            for (int i = 0; i < paramList.Length; i++)
            {
                invokeArgs[i + 1] = paramList[i];
            }
            // 调用委托。
            Expression invokeDlg = Expression.Invoke(getDlg, invokeArgs);

            return(Expression.Lambda <TDelegate>(invokeDlg, paramList).Compile() as TDelegate);
        }
コード例 #3
0
        /// <summary>
        /// 使用指定的关键参数索引和方法委托列表初始化
        /// <see cref="MethodSwitcherManual&lt;TDelegate&gt;"/> 类的新实例。
        /// </summary>
        /// <param name="idx">关键参数的索引。</param>
        /// <param name="methods">使用不同子类作为参数的方法列表。</param>
        /// <exception cref="System.ArgumentException"><typeparamref name="TDelegate"/> 不继承
        /// <see cref="System.MulticastDelegate"/>。</exception>
        /// <exception cref="System.ArgumentOutOfRangeException"><paramref name="idx"/>
        /// 小于零或者大于等于 <typeparamref name="TDelegate"/> 的参数个数。</exception>
        /// <exception cref="System.ArgumentNullException"><paramref name="methods"/>
        /// 中存在为 <c>null</c> 的方法。</exception>
        /// <exception cref="System.ArgumentException"><paramref name="methods"/>
        /// 中存在不与 <typeparamref name="TDelegate"/> 兼容的方法。</exception>
        public MethodSwitcherManual(int idx, params Delegate[] methods)
        {
            ExceptionHelper.CheckArgumentNull(methods, "methods");
            Type dlgType = typeof(TDelegate);

            ExceptionHelper.CheckDelegateType(dlgType, "TDelegate");
            ParameterInfo[] paramInfos = dlgType.GetMethod("Invoke").GetParameters();
            int             len        = paramInfos.Length;

            if (idx < 0 || idx >= len)
            {
                throw ExceptionHelper.ArgumentOutOfRange("idx");
            }
            keyIndex = idx;
            InitMethods(methods);
            BuildInvoke(paramInfos);
        }