Beispiel #1
0
        /// <summary>
        /// 创建指定的静态或实例属性的指定类型的封闭属性委托。
        /// </summary>
        /// <param name="property">要获取或设置的属性。</param>
        /// <param name="delegateType">要创建的委托的类型。</param>
        /// <param name="firstArgument">如果是实例属性,则作为委托要绑定到的对象;否则将作为属性的第一个参数。</param>
        /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="property"/>
        /// 时引发异常;否则为 <c>false</c>。</param>
        /// <param name="ensureClosed">如果确认属性一定是封闭委托,则为 <c>true</c>;若
        /// <paramref name="firstArgument"/> 为 <c>null</c> 时可能为开放委托,则为 <c>false</c>。</param>
        /// <returns><paramref name="delegateType"/> 类型的委托,表示静态或实例属性的委托。</returns>
        /// <remarks>如果委托具有返回值,则认为是获取属性,否则认为是设置属性。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        private static Delegate CreateClosedDelegate(PropertyInfo property, Type delegateType, object firstArgument,
                                                     bool throwOnBindFailure, bool ensureClosed)
        {
            Contract.Requires(property != null && delegateType != null);
            var invoke = delegateType.GetInvokeMethod();
            // 判断是获取属性还是设置属性。
            MethodInfo method;

            if (invoke.ReturnType == typeof(void))
            {
                method = property.GetSetMethod(true);
                if (method == null)
                {
                    if (throwOnBindFailure)
                    {
                        throw CommonExceptions.BindTargetPropertyNoSet(nameof(property));
                    }
                    return(null);
                }
            }
            else
            {
                method = property.GetGetMethod(true);
                if (method == null)
                {
                    if (throwOnBindFailure)
                    {
                        throw CommonExceptions.BindTargetPropertyNoGet(nameof(property));
                    }
                    return(null);
                }
            }
            // 创建委托。
            var dlg = CreateClosedDelegate(method, delegateType, firstArgument, ensureClosed);

            if (dlg == null && throwOnBindFailure)
            {
                throw CommonExceptions.BindTargetProperty(nameof(property));
            }
            return(dlg);
        }
        /// <summary>
        /// 创建指定的静态或实例属性的指定类型的开放属性委托。
        /// </summary>
        /// <param name="property">要获取或设置的属性。</param>
        /// <param name="delegateType">要创建的委托的类型。</param>
        /// <param name="throwOnBindFailure">为 <c>true</c>,表示无法绑定 <paramref name="property"/>
        ///     时引发异常;否则为 <c>false</c>。</param>
        /// <returns><paramref name="delegateType"/> 类型的委托,表示静态或实例属性的委托。</returns>
        /// <remarks>如果是实例属性,需要将实例对象作为委托的第一个参数。
        /// 如果委托具有返回值,则认为是获取属性,否则认为是设置属性。
        /// 支持参数的强制类型转换,参数声明可以与实际类型不同。</remarks>
        private static Delegate CreateOpenDelegate(PropertyInfo property, Type delegateType, bool throwOnBindFailure)
        {
            Contract.Requires(property != null && delegateType != null);
            MethodInfo invoke = delegateType.GetInvokeMethod();
            // 判断是获取属性还是设置属性。
            MethodInfo method;

            if (invoke.ReturnType == typeof(void))
            {
                method = property.GetSetMethod(true);
                if (method == null)
                {
                    if (throwOnBindFailure)
                    {
                        throw CommonExceptions.BindTargetPropertyNoSet("property");
                    }
                    return(null);
                }
            }
            else
            {
                method = property.GetGetMethod(true);
                if (method == null)
                {
                    if (throwOnBindFailure)
                    {
                        throw CommonExceptions.BindTargetPropertyNoGet("property");
                    }
                    return(null);
                }
            }
            // 创建委托。
            Delegate dlg = CreateOpenDelegate(method, delegateType);

            if (dlg == null && throwOnBindFailure)
            {
                throw CommonExceptions.BindTargetProperty("property");
            }
            return(dlg);
        }