예제 #1
0
        /// <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
        {
            CommonExceptions.CheckArgumentNull(type, "type");
            Type dlgType = typeof(TDelegate);

            CommonExceptions.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
        /// <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
        {
            CommonExceptions.CheckArgumentNull(target, "target");
            Type dlgType = typeof(TDelegate);

            CommonExceptions.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>
 /// 使用针对绑定失败的指定行为,创建用于表示获取或设置指定静态或实例属性的指定类型的委托。
 /// </summary>
 /// <param name="property">描述委托要表示的静态或实例属性的 <see cref="PropertyInfo"/>。</param>
 /// <param name="delegateType">要创建的委托的类型。</param>
 /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="property"/>
 ///     时引发异常;否则为 <c>false</c>。</param>
 /// <returns>指定类型的委托,表示获取或设置指定的静态或实例属性。</returns>
 /// <remarks>如果是实例属性,需要将实例对象作为委托的第一个参数。
 /// 如果委托具有返回值,则认为是获取属性,否则认为是设置属性。
 /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
 /// <exception cref="ArgumentNullException"><paramref name="property"/> 为 <c>null</c>。</exception>
 /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
 /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
 /// <exception cref="ArgumentException">无法绑定 <paramref name="property"/>
 /// 且 <paramref name="throwOnBindFailure"/> 为 <c>true</c>。</exception>
 /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="property"/>。</exception>
 public static Delegate CreateDelegate(this PropertyInfo property, Type delegateType, bool throwOnBindFailure)
 {
     CommonExceptions.CheckArgumentNull(property, nameof(property));
     CommonExceptions.CheckArgumentNull(delegateType, nameof(delegateType));
     Contract.EndContractBlock();
     CommonExceptions.CheckDelegateType(delegateType, nameof(delegateType));
     CommonExceptions.CheckUnboundGenParam(property, nameof(property));
     return(CreateOpenDelegate(property, delegateType, throwOnBindFailure));
 }
예제 #4
0
 /// <summary>
 /// 使用针对绑定失败的指定行为,创建用于表示获取或设置指定静态或实例属性的指定类型的委托。
 /// </summary>
 /// <param name="property">描述委托要表示的静态或实例属性的 <see cref="PropertyInfo"/>。</param>
 /// <param name="delegateType">要创建的委托的类型。</param>
 /// <returns>指定类型的委托,表示获取或设置指定的静态或实例属性。</returns>
 /// <remarks>如果是实例属性,需要将实例对象作为委托的第一个参数。
 /// 如果委托具有返回值,则认为是获取属性,否则认为是设置属性。
 /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
 /// <exception cref="ArgumentNullException"><paramref name="property"/> 为 <c>null</c>。</exception>
 /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
 /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
 /// <exception cref="ArgumentException">无法绑定 <paramref name="property"/>。</exception>
 /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="property"/>。</exception>
 public static Delegate CreateDelegate(this PropertyInfo property, Type delegateType)
 {
     CommonExceptions.CheckArgumentNull(property, nameof(property));
     CommonExceptions.CheckArgumentNull(delegateType, nameof(delegateType));
     Contract.Ensures(Contract.Result <Delegate>() != null);
     CommonExceptions.CheckDelegateType(delegateType, nameof(delegateType));
     CommonExceptions.CheckUnboundGenParam(property, nameof(property));
     return(CreateOpenDelegate(property, delegateType, true));
 }
예제 #5
0
 /// <summary>
 /// 使用指定的第一个参数,创建用于表示获取或设置指定的静态或实例属性的指定类型的委托。
 /// </summary>
 /// <param name="property">描述委托要表示的静态或实例属性的 <see cref="PropertyInfo"/>。</param>
 /// <param name="delegateType">要创建的委托的类型。</param>
 /// <param name="firstArgument">如果是实例属性,则作为委托要绑定到的对象;否则将作为属性的第一个参数。</param>
 /// <returns>指定类型的委托,表示获取或设置指定的静态或实例属性。</returns>
 /// <remarks>如果委托具有返回值,则认为是获取属性,否则认为是设置属性。
 /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
 /// <exception cref="ArgumentNullException"><paramref name="property"/> 为 <c>null</c>。</exception>
 /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
 /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
 /// <exception cref="ArgumentException">无法绑定 <paramref name="property"/>。</exception>
 /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="property"/>。</exception>
 public static Delegate CreateDelegate(this PropertyInfo property, Type delegateType, object firstArgument)
 {
     CommonExceptions.CheckArgumentNull(property, "property");
     CommonExceptions.CheckArgumentNull(delegateType, "delegateType");
     Contract.Ensures(Contract.Result <Delegate>() != null);
     CommonExceptions.CheckDelegateType(delegateType, "delegateType");
     CommonExceptions.CheckUnboundGenParam(property, "property");
     return(CreateClosedDelegate(property, delegateType, firstArgument, true, false));
 }
예제 #6
0
        /// <summary>
        /// 创建指定对象中与默认指定相关的实例方法切换器,会自动推断关键参数(使用不同子类的参数,必须是唯一的)。
        /// </summary>
        /// <typeparam name="TDelegate">使用基类型调用方法的委托。</typeparam>
        /// <param name="target">在其中查找实例方法的对象。</param>
        /// <returns><paramref name="target"/> 中与默认标识相关的实例方法切换器。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="target"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">委托类型与处理器不匹配。</exception>
        /// <exception cref="ArgumentException">处理器的参数不匹配。</exception>
        /// <exception cref="ArgumentException">没有找到唯一的关键参数。</exception>
        public static TDelegate Create <TDelegate>(object target)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(target, nameof(target));
            Contract.Ensures(Contract.Result <TDelegate>() != null);
            CommonExceptions.CheckDelegateType(typeof(TDelegate));
            var data = GetMethods <TDelegate>(target.GetType(), ProcessorAttribute.DefaultId, false);

            return(CreateSwitcher <TDelegate>(data, ProcessorAttribute.DefaultId, target));
        }
예제 #7
0
 /// <summary>
 /// 使用指定的第一个参数和针对绑定失败的指定行为,创建用于表示获取或设置指定的静态或实例属性的指定类型的委托。
 /// </summary>
 /// <param name="property">描述委托要表示的静态或实例属性的 <see cref="PropertyInfo"/>。</param>
 /// <param name="delegateType">要创建的委托的类型。</param>
 /// <param name="firstArgument">如果是实例属性,则作为委托要绑定到的对象;否则将作为属性的第一个参数。</param>
 /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="property"/>
 ///     时引发异常;否则为 <c>false</c>。</param>
 /// <returns>指定类型的委托,表示获取或设置指定的静态或实例属性。</returns>
 /// <remarks>如果委托具有返回值,则认为是获取属性,否则认为是设置属性。
 /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
 /// <exception cref="ArgumentNullException"><paramref name="property"/> 为 <c>null</c>。</exception>
 /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
 /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
 /// <exception cref="ArgumentException">无法绑定 <paramref name="property"/>
 /// 且 <paramref name="throwOnBindFailure"/> 为 <c>true</c>。</exception>
 /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="property"/>。</exception>
 public static Delegate CreateDelegate(this PropertyInfo property, Type delegateType, object firstArgument,
                                       bool throwOnBindFailure)
 {
     CommonExceptions.CheckArgumentNull(property, "property");
     CommonExceptions.CheckArgumentNull(delegateType, "delegateType");
     Contract.EndContractBlock();
     CommonExceptions.CheckDelegateType(delegateType, "delegateType");
     CommonExceptions.CheckUnboundGenParam(property, "property");
     return(CreateClosedDelegate(property, delegateType, firstArgument, throwOnBindFailure, false));
 }
예제 #8
0
        /// <summary>
        /// 创建指定类型中与默认标识相关的静态方法切换器,会自动推断关键参数(使用不同子类的参数,必须是唯一的)。
        /// </summary>
        /// <typeparam name="TDelegate">使用基类型调用方法的委托。</typeparam>
        /// <param name="type">在其中查找静态方法的类型。</param>
        /// <returns><paramref name="type"/> 中与默认标识相关的静态方法切换器。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="type"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">委托类型与处理器不匹配。</exception>
        /// <exception cref="ArgumentException">处理器的参数不匹配。</exception>
        /// <exception cref="ArgumentException">没有找到唯一的关键参数。</exception>
        public static TDelegate Create <TDelegate>(Type type)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(type, "type");
            Contract.Ensures(Contract.Result <TDelegate>() != null);
            CommonExceptions.CheckDelegateType(typeof(TDelegate));
            ProcessorData data = GetMethods <TDelegate>(type, ProcessorAttribute.DefaultId, true);

            return(CreateSwitcher <TDelegate>(data, ProcessorAttribute.DefaultId, null));
        }
예제 #9
0
        /// <summary>
        /// 创建用于表示获取或设置指定静态或实例属性的指定类型的委托。
        /// </summary>
        /// <typeparam name="TDelegate">要创建的委托的类型。</typeparam>
        /// <param name="property">描述委托要表示的静态或实例属性的 <see cref="PropertyInfo"/>。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例属性。</returns>
        /// <remarks>如果是实例属性,需要将实例对象作为委托的第一个参数。
        /// 如果委托具有返回值,则认为是获取属性,否则认为是设置属性。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="property"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="property"/> 。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="property"/>。</exception>
        public static TDelegate CreateDelegate <TDelegate>(this PropertyInfo property)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(property, nameof(property));
            Contract.Ensures(Contract.Result <TDelegate>() != null);
            var type = typeof(TDelegate);

            CommonExceptions.CheckDelegateType(type);
            CommonExceptions.CheckUnboundGenParam(property, nameof(property));
            return(CreateOpenDelegate(property, type, true) as TDelegate);
        }
예제 #10
0
        /// <summary>
        /// 使用指定的第一个参数,创建用于表示获取或设置指定的静态或实例属性的指定类型的委托。
        /// </summary>
        /// <typeparam name="TDelegate">要创建的委托的类型。</typeparam>
        /// <param name="property">描述委托要表示的静态或实例属性的 <see cref="PropertyInfo"/>。</param>
        /// <param name="firstArgument">如果是实例属性,则作为委托要绑定到的对象;否则将作为属性的第一个参数。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例属性。</returns>
        /// <remarks>如果委托具有返回值,则认为是获取属性,否则认为是设置属性。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="property"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="property"/>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="property"/>。</exception>
        public static TDelegate CreateDelegate <TDelegate>(this PropertyInfo property, object firstArgument)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(property, "property");
            Contract.Ensures(Contract.Result <TDelegate>() != null);
            Type type = typeof(TDelegate);

            CommonExceptions.CheckDelegateType(type);
            CommonExceptions.CheckUnboundGenParam(property, "property");
            return(CreateClosedDelegate(property, type, firstArgument, true, false) as TDelegate);
        }
예제 #11
0
        /// <summary>
        /// 使用针对绑定失败的指定行为,创建用于表示获取或设置指定静态或实例属性的指定类型的委托。
        /// </summary>
        /// <typeparam name="TDelegate">要创建的委托的类型。</typeparam>
        /// <param name="property">描述委托要表示的静态或实例属性的 <see cref="PropertyInfo"/>。</param>
        /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="property"/>
        /// 时引发异常;否则为 <c>false</c>。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例属性。</returns>
        /// <remarks>如果是实例属性,需要将实例对象作为委托的第一个参数。
        /// 如果委托具有返回值,则认为是获取属性,否则认为是设置属性。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="property"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="property"/>
        /// 且 <paramref name="throwOnBindFailure"/> 为 <c>true</c>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="property"/>。</exception>
        public static TDelegate CreateDelegate <TDelegate>(this PropertyInfo property, bool throwOnBindFailure)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(property, nameof(property));
            Contract.EndContractBlock();
            var type = typeof(TDelegate);

            CommonExceptions.CheckDelegateType(type);
            CommonExceptions.CheckUnboundGenParam(property, nameof(property));
            return(CreateOpenDelegate(property, type, throwOnBindFailure) as TDelegate);
        }
예제 #12
0
        /// <summary>
        /// 创建与指定委托列表相关的方法切换器,会自动推断关键参数(使用不同子类的参数,必须是唯一的)。
        /// </summary>
        /// <typeparam name="TDelegate">使用基类型调用方法的委托类型。</typeparam>
        /// <param name="delegates">使用不同子类作为参数的委托列表。</param>
        /// <returns>与 <paramref name="delegates"/> 相关的方法切换器。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="delegates"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="delegates"/> 中存在为 <c>null</c> 的委托。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">委托类型与处理器不匹配。</exception>
        /// <exception cref="ArgumentException">处理器的参数不匹配。</exception>
        /// <exception cref="ArgumentException">没有找到唯一的关键参数。</exception>
        /// <overloads>
        /// <summary>
        /// 创建方法切换器,会自动推断关键参数(使用不同子类的参数,必须是唯一的)。
        /// </summary>
        /// </overloads>
        public static TDelegate Create <TDelegate>(params Delegate[] delegates)
            where TDelegate : class
        {
            CommonExceptions.CheckCollectionItemNull(delegates, nameof(delegates));
            Contract.Ensures(Contract.Result <TDelegate>() != null);
            CommonExceptions.CheckDelegateType(typeof(TDelegate));
            var data = new ProcessorData(delegates);

            CheckDelegateType <TDelegate>(data);
            return(CreateSwitcher <TDelegate>(data, null, null));
        }
예제 #13
0
        /// <summary>
        /// 创建指定对象中与标识指定相关的实例方法切换器,会自动推断关键参数(使用不同子类的参数,必须是唯一的)。
        /// </summary>
        /// <typeparam name="TDelegate">使用基类型调用方法的委托。</typeparam>
        /// <param name="target">在其中查找实例方法的对象。</param>
        /// <param name="id">处理器的标识。</param>
        /// <returns><paramref name="target"/> 中与指定标识相关的实例方法切换器。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="target"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="id"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="id"/> 为空字符串。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">委托类型与处理器不匹配。</exception>
        /// <exception cref="ArgumentException">处理器的参数不匹配。</exception>
        /// <exception cref="ArgumentException">没有找到唯一的关键参数。</exception>
        public static TDelegate Create <TDelegate>(object target, string id)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(target, nameof(target));
            CommonExceptions.CheckStringEmpty(id, nameof(id));
            Contract.Ensures(Contract.Result <TDelegate>() != null);
            CommonExceptions.CheckDelegateType(typeof(TDelegate));
            var data = GetMethods <TDelegate>(target.GetType(), id, false);

            return(CreateSwitcher <TDelegate>(data, id, target));
        }
예제 #14
0
        /// <summary>
        /// 创建指定类型中与标识指定相关的静态方法切换器,会自动推断关键参数(使用不同子类的参数,必须是唯一的)。
        /// </summary>
        /// <typeparam name="TDelegate">使用基类型调用方法的委托。</typeparam>
        /// <param name="type">在其中查找静态方法的类型。</param>
        /// <param name="id">处理器的标识。</param>
        /// <returns><paramref name="type"/> 中与指定标识相关的静态方法切换器。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="type"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="id"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="id"/> 为空字符串。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">委托类型与处理器不匹配。</exception>
        /// <exception cref="ArgumentException">处理器的参数不匹配。</exception>
        /// <exception cref="ArgumentException">没有找到唯一的关键参数。</exception>
        public static TDelegate Create <TDelegate>(Type type, string id)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(type, "type");
            CommonExceptions.CheckStringEmpty(id, "id");
            Contract.Ensures(Contract.Result <TDelegate>() != null);
            CommonExceptions.CheckDelegateType(typeof(TDelegate));
            ProcessorData data = GetMethods <TDelegate>(type, id, true);

            return(CreateSwitcher <TDelegate>(data, id, null));
        }
예제 #15
0
        /// <summary>
        /// 使用指定的第一个参数和针对绑定失败的指定行为,创建用于表示获取或设置指定的静态或实例属性的指定类型的委托。
        /// </summary>
        /// <typeparam name="TDelegate">要创建的委托的类型。</typeparam>
        /// <param name="property">描述委托要表示的静态或实例属性的 <see cref="PropertyInfo"/>。</param>
        /// <param name="firstArgument">如果是实例属性,则作为委托要绑定到的对象;否则将作为属性的第一个参数。</param>
        /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="property"/>
        /// 时引发异常;否则为 <c>false</c>。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例属性。</returns>
        /// <remarks>如果委托具有返回值,则认为是获取属性,否则认为是设置属性。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="property"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="property"/>
        /// 且 <paramref name="throwOnBindFailure"/> 为 <c>true</c>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="property"/>。</exception>
        public static TDelegate CreateDelegate <TDelegate>(this PropertyInfo property, object firstArgument,
                                                           bool throwOnBindFailure)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(property, "property");
            Contract.EndContractBlock();
            Type type = typeof(TDelegate);

            CommonExceptions.CheckDelegateType(type);
            CommonExceptions.CheckUnboundGenParam(property, "property");
            return(CreateClosedDelegate(property, type, firstArgument, throwOnBindFailure, false) as TDelegate);
        }
예제 #16
0
 /// <summary>
 /// 将指定的委托用指定类型的委托包装,支持对参数进行强制类型转换。
 /// </summary>
 /// <param name="dlg">要被包装的委托。</param>
 /// <param name="delegateType">要创建的委托的类型。</param>
 /// <returns>指定类型的委托,其包装了 <paramref name="dlg"/>。
 /// 如果参数个数不同,或者参数间不能执行强制类型转换,则为 <c>null</c>。</returns>
 /// <exception cref="ArgumentNullException"><paramref name="dlg"/> 为 <c>null</c>。</exception>
 /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
 /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
 /// <exception cref="MethodAccessException">调用方无权访问成员。</exception>
 public static Delegate Wrap(this Delegate dlg, Type delegateType)
 {
     CommonExceptions.CheckArgumentNull(dlg, "dlg");
     CommonExceptions.CheckArgumentNull(delegateType, "delegateType");
     Contract.EndContractBlock();
     if (delegateType.IsInstanceOfType(dlg))
     {
         return(dlg);
     }
     CommonExceptions.CheckDelegateType(delegateType, "delegateType");
     return(CreateClosedDelegate(dlg.Method, delegateType, dlg.Target, false));
 }
예제 #17
0
        /// <summary>
        /// 使用针对绑定失败的指定行为,创建用于表示获取或设置指定静态或实例字段的指定类型的委托。
        /// </summary>
        /// <param name="field">描述委托要表示的静态或实例字段的 <see cref="FieldInfo"/>。</param>
        /// <param name="delegateType">要创建的委托的类型。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例字段。</returns>
        /// <remarks>如果是实例字段,需要将实例对象作为委托的第一个参数。
        /// 如果委托具有返回值,则认为是获取字段,否则认为是设置字段。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="field"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="field"/>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="field"/>。</exception>
        public static Delegate CreateDelegate(this FieldInfo field, Type delegateType)
        {
            CommonExceptions.CheckArgumentNull(field, "field");
            CommonExceptions.CheckArgumentNull(delegateType, "delegateType");
            Contract.Ensures(Contract.Result <Delegate>() != null);
            CommonExceptions.CheckDelegateType(delegateType, "delegateType");
            CommonExceptions.CheckUnboundGenParam(field, "field");
            Delegate dlg = CreateOpenDelegate(field, delegateType);

            if (dlg == null)
            {
                throw CommonExceptions.BindTargetField("field");
            }
            return(dlg);
        }
예제 #18
0
        /// <summary>
        /// 使用指定的第一个参数,创建用于表示获取或设置指定的静态或实例字段的指定类型的委托。
        /// </summary>
        /// <param name="field">描述委托要表示的静态或实例字段的 <see cref="FieldInfo"/>。</param>
        /// <param name="delegateType">要创建的委托的类型。</param>
        /// <param name="firstArgument">如果是实例字段,则作为委托要绑定到的对象;否则将作为字段的第一个参数。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例字段。</returns>
        /// <remarks>如果委托具有返回值,则认为是获取字段,否则认为是设置字段。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="field"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="field"/>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="field"/>。</exception>
        public static Delegate CreateDelegate(this FieldInfo field, Type delegateType, object firstArgument)
        {
            CommonExceptions.CheckArgumentNull(field, nameof(field));
            CommonExceptions.CheckArgumentNull(delegateType, nameof(delegateType));
            Contract.Ensures(Contract.Result <Delegate>() != null);
            CommonExceptions.CheckDelegateType(delegateType, nameof(delegateType));
            CommonExceptions.CheckUnboundGenParam(field, nameof(field));
            var dlg = CreateClosedDelegate(field, delegateType, firstArgument);

            if (dlg == null)
            {
                throw CommonExceptions.BindTargetField(nameof(field));
            }
            return(dlg);
        }
예제 #19
0
        /// <summary>
        /// 使用针对绑定失败的指定行为,创建用于表示获取或设置指定静态或实例字段的指定类型的委托。
        /// </summary>
        /// <param name="field">描述委托要表示的静态或实例字段的 <see cref="FieldInfo"/>。</param>
        /// <param name="delegateType">要创建的委托的类型。</param>
        /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="field"/>
        /// 时引发异常;否则为 <c>false</c>。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例字段。</returns>
        /// <remarks>如果是实例字段,需要将实例对象作为委托的第一个参数。
        /// 如果委托具有返回值,则认为是获取字段,否则认为是设置字段。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="field"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="field"/>
        /// 且 <paramref name="throwOnBindFailure"/> 为 <c>true</c>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="field"/>。</exception>
        public static Delegate CreateDelegate(this FieldInfo field, Type delegateType, bool throwOnBindFailure)
        {
            CommonExceptions.CheckArgumentNull(field, "field");
            CommonExceptions.CheckArgumentNull(delegateType, "delegateType");
            Contract.EndContractBlock();
            CommonExceptions.CheckDelegateType(delegateType, "delegateType");
            CommonExceptions.CheckUnboundGenParam(field, "field");
            Delegate dlg = CreateOpenDelegate(field, delegateType);

            if (dlg == null && throwOnBindFailure)
            {
                throw CommonExceptions.BindTargetField("field");
            }
            return(dlg);
        }
예제 #20
0
        /// <summary>
        /// 将指定的委托用指定类型的委托包装,支持对参数进行强制类型转换。
        /// </summary>
        /// <typeparam name="TDelegate">要创建的委托的类型。</typeparam>
        /// <param name="dlg">要被包装的委托。</param>
        /// <returns>指定类型的委托,其包装了 <paramref name="dlg"/>。
        /// 如果参数个数不同,或者参数间不能执行强制类型转换,则为 <c>null</c>。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="dlg"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问成员。</exception>
        /// <overloads>
        /// <summary>
        /// 将指定的委托用指定类型的委托包装,支持对参数进行强制类型转换。
        /// </summary>
        /// </overloads>
        public static TDelegate Wrap <TDelegate>(this Delegate dlg)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(dlg, "dlg");
            Contract.EndContractBlock();
            TDelegate typedDlg = dlg as TDelegate;

            if (typedDlg != null)
            {
                return(typedDlg);
            }
            Type type = typeof(TDelegate);

            CommonExceptions.CheckDelegateType(type);
            return(CreateClosedDelegate(dlg.Method, type, dlg.Target, false) as TDelegate);
        }
예제 #21
0
        /// <summary>
        /// 使用指定的第一个参数和针对绑定失败的指定行为,创建用于表示获取或设置指定的静态或实例字段的指定类型的委托。
        /// </summary>
        /// <param name="field">描述委托要表示的静态或实例字段的 <see cref="FieldInfo"/>。</param>
        /// <param name="delegateType">要创建的委托的类型。</param>
        /// <param name="firstArgument">如果是实例字段,则作为委托要绑定到的对象;否则将作为字段的第一个参数。</param>
        /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="field"/>
        /// 时引发异常;否则为 <c>false</c>。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例字段。</returns>
        /// <remarks>如果委托具有返回值,则认为是获取字段,否则认为是设置字段。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="field"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="field"/>
        /// 且 <paramref name="throwOnBindFailure"/> 为 <c>true</c>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="field"/>。</exception>
        public static Delegate CreateDelegate(this FieldInfo field, Type delegateType, object firstArgument,
                                              bool throwOnBindFailure)
        {
            CommonExceptions.CheckArgumentNull(field, nameof(field));
            CommonExceptions.CheckArgumentNull(delegateType, nameof(delegateType));
            Contract.EndContractBlock();
            CommonExceptions.CheckDelegateType(delegateType, nameof(delegateType));
            CommonExceptions.CheckUnboundGenParam(field, nameof(field));
            var dlg = CreateClosedDelegate(field, delegateType, firstArgument);

            if (dlg == null && throwOnBindFailure)
            {
                throw CommonExceptions.BindTargetField(nameof(field));
            }
            return(dlg);
        }
예제 #22
0
        /// <summary>
        /// 创建用于表示获取或设置指定静态或实例字段的指定类型的委托。
        /// </summary>
        /// <typeparam name="TDelegate">要创建的委托的类型。</typeparam>
        /// <param name="field">描述委托要表示的静态或实例字段的 <see cref="FieldInfo"/>。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例字段。</returns>
        /// <remarks>如果是实例字段,需要将实例对象作为委托的第一个参数。
        /// 如果委托具有返回值,则认为是获取字段,否则认为是设置字段。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="field"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="field"/> 。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="field"/>。</exception>
        public static TDelegate CreateDelegate <TDelegate>(this FieldInfo field)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(field, nameof(field));
            Contract.Ensures(Contract.Result <TDelegate>() != null);
            var type = typeof(TDelegate);

            CommonExceptions.CheckDelegateType(type);
            CommonExceptions.CheckUnboundGenParam(field, nameof(field));
            var dlg = CreateOpenDelegate(field, type);

            if (dlg == null)
            {
                throw CommonExceptions.BindTargetField(nameof(field));
            }
            return(dlg as TDelegate);
        }
예제 #23
0
        /// <summary>
        /// 使用针对绑定失败的指定行为,创建用于表示获取或设置指定静态或实例字段的指定类型的委托。
        /// </summary>
        /// <typeparam name="TDelegate">要创建的委托的类型。</typeparam>
        /// <param name="field">描述委托要表示的静态或实例字段的 <see cref="FieldInfo"/>。</param>
        /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="field"/>
        /// 时引发异常;否则为 <c>false</c>。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例字段。</returns>
        /// <remarks>如果是实例字段,需要将实例对象作为委托的第一个参数。
        /// 如果委托具有返回值,则认为是获取字段,否则认为是设置字段。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="field"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="field"/>
        /// 且 <paramref name="throwOnBindFailure"/> 为 <c>true</c>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="field"/>。</exception>
        public static TDelegate CreateDelegate <TDelegate>(this FieldInfo field, bool throwOnBindFailure)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(field, "field");
            Contract.EndContractBlock();
            Type type = typeof(TDelegate);

            CommonExceptions.CheckDelegateType(type);
            CommonExceptions.CheckUnboundGenParam(field, "field");
            Delegate dlg = CreateOpenDelegate(field, type);

            if (dlg == null && throwOnBindFailure)
            {
                throw CommonExceptions.BindTargetField("field");
            }
            return(dlg as TDelegate);
        }
예제 #24
0
        /// <summary>
        /// 使用指定的第一个参数,创建用于表示获取或设置指定的静态或实例字段的指定类型的委托。
        /// </summary>
        /// <typeparam name="TDelegate">要创建的委托的类型。</typeparam>
        /// <param name="field">描述委托要表示的静态或实例字段的 <see cref="FieldInfo"/>。</param>
        /// <param name="firstArgument">如果是实例字段,则作为委托要绑定到的对象;否则将作为字段的第一个参数。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例字段。</returns>
        /// <remarks>如果委托具有返回值,则认为是获取字段,否则认为是设置字段。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="field"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="field"/>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="field"/>。</exception>
        public static TDelegate CreateDelegate <TDelegate>(this FieldInfo field, object firstArgument)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(field, "field");
            Contract.Ensures(Contract.Result <TDelegate>() != null);
            Type type = typeof(TDelegate);

            CommonExceptions.CheckDelegateType(type);
            CommonExceptions.CheckUnboundGenParam(field, "field");
            Delegate dlg = CreateClosedDelegate(field, type, firstArgument);

            if (dlg == null)
            {
                throw CommonExceptions.BindTargetField("field");
            }
            return(dlg as TDelegate);
        }
예제 #25
0
        /// <summary>
        /// 使用指定的关键参数索引和方法委托列表初始化
        /// <see cref="MethodSwitcherManual{TDelegate}"/> 类的新实例。
        /// </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)
        {
            CommonExceptions.CheckArgumentNull(methods, "methods");
            Type dlgType = typeof(TDelegate);

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

            if (idx < 0 || idx >= len)
            {
                throw CommonExceptions.ArgumentOutOfRange("idx", idx);
            }
            keyIndex = idx;
            InitMethods(methods);
            BuildInvoke(paramInfos);
        }
예제 #26
0
        /// <summary>
        /// 使用指定的第一个参数和针对绑定失败的指定行为,创建用于表示获取或设置指定的静态或实例字段的指定类型的委托。
        /// </summary>
        /// <typeparam name="TDelegate">要创建的委托的类型。</typeparam>
        /// <param name="field">描述委托要表示的静态或实例字段的 <see cref="FieldInfo"/>。</param>
        /// <param name="firstArgument">如果是实例字段,则作为委托要绑定到的对象;否则将作为字段的第一个参数。</param>
        /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="field"/>
        /// 时引发异常;否则为 <c>false</c>。</param>
        /// <returns>指定类型的委托,表示获取或设置指定的静态或实例字段。</returns>
        /// <remarks>如果委托具有返回值,则认为是获取字段,否则认为是设置字段。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="field"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><typeparamref name="TDelegate"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="field"/>
        /// 且 <paramref name="throwOnBindFailure"/> 为 <c>true</c>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="field"/>。</exception>
        public static TDelegate CreateDelegate <TDelegate>(this FieldInfo field, object firstArgument,
                                                           bool throwOnBindFailure)
            where TDelegate : class
        {
            CommonExceptions.CheckArgumentNull(field, nameof(field));
            Contract.EndContractBlock();
            var type = typeof(TDelegate);

            CommonExceptions.CheckDelegateType(type);
            CommonExceptions.CheckUnboundGenParam(field, nameof(field));
            var dlg = CreateClosedDelegate(field, type, firstArgument);

            if (dlg == null && throwOnBindFailure)
            {
                throw CommonExceptions.BindTargetField(nameof(field));
            }
            return(dlg as TDelegate);
        }
예제 #27
0
        /// <summary>
        /// 创建用于表示指定静态或实例方法的指定类型的委托。
        /// </summary>
        /// <param name="method">描述委托要表示的静态或实例方法的 <see cref="MethodBase"/>。</param>
        /// <param name="delegateType">要创建的委托的类型。</param>
        /// <returns>指定类型的委托,表示指定的静态或实例方法。</returns>
        /// <remarks>如果是实例方法(非构造函数),需要将实例对象作为委托的第一个参数。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="method"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="method"/>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="method"/>。</exception>
        public static Delegate CreateDelegate(this MethodBase method, Type delegateType)
        {
            CommonExceptions.CheckArgumentNull(method, nameof(method));
            CommonExceptions.CheckArgumentNull(delegateType, nameof(delegateType));
            Contract.Ensures(Contract.Result <Delegate>() != null);
            CommonExceptions.CheckDelegateType(delegateType, nameof(delegateType));
            CommonExceptions.CheckUnboundGenParam(method, nameof(method));
            if (method.ContainsGenericParameters && !method.IsGenericMethodDefinition)
            {
                throw CommonExceptions.UnboundGenParam(nameof(method));
            }
            var dlg = CreateOpenDelegate(method, delegateType);

            if (dlg == null)
            {
                throw CommonExceptions.BindTargetMethod(nameof(method));
            }
            return(dlg);
        }
예제 #28
0
        /// <summary>
        /// 使用针对绑定失败的指定行为,创建用于表示指定静态或实例方法的指定类型的委托。
        /// </summary>
        /// <param name="method">描述委托要表示的静态或实例方法的 <see cref="MethodBase"/>。</param>
        /// <param name="delegateType">要创建的委托的类型。</param>
        /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="method"/>
        /// 时引发异常;否则为 <c>false</c>。</param>
        /// <returns>指定类型的委托,表示指定的静态或实例方法。</returns>
        /// <remarks>如果是实例方法(非构造函数),需要将实例对象作为委托的第一个参数。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="method"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="method"/>
        /// 且 <paramref name="throwOnBindFailure"/> 为 <c>true</c>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="method"/>。</exception>
        public static Delegate CreateDelegate(this MethodBase method, Type delegateType, bool throwOnBindFailure)
        {
            CommonExceptions.CheckArgumentNull(method, "method");
            CommonExceptions.CheckArgumentNull(delegateType, "delegateType");
            Contract.EndContractBlock();
            CommonExceptions.CheckDelegateType(delegateType, "delegateType");
            CommonExceptions.CheckUnboundGenParam(method, "method");
            if (method.ContainsGenericParameters && !method.IsGenericMethodDefinition)
            {
                throw CommonExceptions.UnboundGenParam("method");
            }
            Delegate dlg = CreateOpenDelegate(method, delegateType);

            if (dlg == null && throwOnBindFailure)
            {
                throw CommonExceptions.BindTargetMethod("method");
            }
            return(dlg);
        }
예제 #29
0
        /// <summary>
        /// 使用指定的第一个参数,创建用于表示指定静态或实例方法的指定类型的委托。
        /// </summary>
        /// <param name="method">描述委托要表示的静态或实例方法的 <see cref="MethodBase"/>。</param>
        /// <param name="delegateType">要创建的委托的类型。</param>
        /// <param name="firstArgument">如果是实例方法(非构造函数),则作为委托要绑定到的对象;
        /// 否则将作为方法的第一个参数。</param>
        /// <returns>指定类型的委托,表示指定的静态或实例方法。</returns>
        /// <remarks>支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="method"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="method"/>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="method"/>。</exception>
        /// <seealso cref="Delegate.CreateDelegate(Type, object, MethodInfo)"/>
        public static Delegate CreateDelegate(this MethodBase method, Type delegateType, object firstArgument)
        {
            CommonExceptions.CheckArgumentNull(method, "method");
            CommonExceptions.CheckArgumentNull(delegateType, "delegateType");
            Contract.Ensures(Contract.Result <Delegate>() != null);
            CommonExceptions.CheckDelegateType(delegateType, "delegateType");
            CommonExceptions.CheckUnboundGenParam(method, "method");
            if (method.ContainsGenericParameters && !method.IsGenericMethodDefinition)
            {
                throw CommonExceptions.UnboundGenParam("method");
            }
            Delegate dlg = CreateClosedDelegate(method, delegateType, firstArgument, false);

            if (dlg == null)
            {
                throw CommonExceptions.BindTargetMethod("method");
            }
            return(dlg);
        }
예제 #30
0
        /// <summary>
        /// 使用指定的第一个参数和针对绑定失败的指定行为,创建用于表示指定静态或实例方法的指定类型的委托。
        /// </summary>
        /// <param name="method">描述委托要表示的静态或实例方法的 <see cref="MethodBase"/>。</param>
        /// <param name="delegateType">要创建的委托的类型。</param>
        /// <param name="firstArgument">如果是实例方法(非构造函数),则作为委托要绑定到的对象;
        ///     否则将作为方法的第一个参数。</param>
        /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="method"/>
        ///     时引发异常;否则为 <c>false</c>。</param>
        /// <returns>指定类型的委托,表示指定的静态或实例方法。</returns>
        /// <remarks>支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="method"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="delegateType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="delegateType"/> 不是委托类型。</exception>
        /// <exception cref="ArgumentException">无法绑定 <paramref name="method"/>
        /// 且 <paramref name="throwOnBindFailure"/> 为 <c>true</c>。</exception>
        /// <exception cref="MethodAccessException">调用方无权访问 <paramref name="method"/>。</exception>
        /// <seealso cref="Delegate.CreateDelegate(Type, object, MethodInfo, bool)"/>
        public static Delegate CreateDelegate(this MethodBase method, Type delegateType, object firstArgument,
                                              bool throwOnBindFailure)
        {
            CommonExceptions.CheckArgumentNull(method, nameof(method));
            CommonExceptions.CheckArgumentNull(delegateType, nameof(delegateType));
            Contract.EndContractBlock();
            CommonExceptions.CheckDelegateType(delegateType, nameof(delegateType));
            CommonExceptions.CheckUnboundGenParam(method, nameof(method));
            if (method.ContainsGenericParameters && !method.IsGenericMethodDefinition)
            {
                throw CommonExceptions.UnboundGenParam(nameof(method));
            }
            var dlg = CreateClosedDelegate(method, delegateType, firstArgument, false);

            if (dlg == null && throwOnBindFailure)
            {
                throw CommonExceptions.BindTargetMethod(nameof(method));
            }
            return(dlg);
        }