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