예제 #1
0
 /// <summary>
 /// 使用要复制的泛型形参的界限集集合初始化 <see cref="TypeBounds"/> 类的新实例。
 /// </summary>
 /// <param name="typeBounds">泛型形参的界限集集合。</param>
 public TypeBounds(TypeBounds typeBounds)
 {
     Contract.Requires(typeBounds != null);
     int len = typeBounds.boundSets.Length;
     this.boundSets = new BoundSet[len];
     this.boundSetDict = new Dictionary<Type, BoundSet>(len);
     for (int i = 0; i < typeBounds.boundSets.Length; i++)
     {
         this.boundSets[i] = new BoundSet(typeBounds.boundSets[i]);
         this.boundSetDict.Add(this.boundSets[i].GenericArgument, this.boundSets[i]);
     }
 }
예제 #2
0
        /// <summary>
        /// 使用要复制的泛型形参的界限集集合初始化 <see cref="TypeBounds"/> 类的新实例。
        /// </summary>
        /// <param name="typeBounds">泛型形参的界限集集合。</param>
        public TypeBounds(TypeBounds typeBounds)
        {
            Contract.Requires(typeBounds != null);
            var len = typeBounds.boundSets.Length;

            boundSets    = new BoundSet[len];
            boundSetDict = new Dictionary <Type, BoundSet>(len);
            for (var i = 0; i < typeBounds.boundSets.Length; i++)
            {
                boundSets[i] = new BoundSet(typeBounds.boundSets[i]);
                boundSetDict.Add(boundSets[i].GenericArgument, boundSets[i]);
            }
        }
예제 #3
0
        /// <summary>
        /// 使用要复制的泛型形参的界限集集合初始化 <see cref="TypeBounds"/> 类的新实例。
        /// </summary>
        /// <param name="typeBounds">泛型形参的界限集集合。</param>
        public TypeBounds(TypeBounds typeBounds)
        {
            Contract.Requires(typeBounds != null);
            int len = typeBounds.boundSets.Length;

            this.boundSets    = new BoundSet[len];
            this.boundSetDict = new Dictionary <Type, BoundSet>(len);
            for (int i = 0; i < typeBounds.boundSets.Length; i++)
            {
                this.boundSets[i] = new BoundSet(typeBounds.boundSets[i]);
                this.boundSetDict.Add(this.boundSets[i].GenericArgument, this.boundSets[i]);
            }
        }
예제 #4
0
        /// <summary>
        /// 检查方法的返回类型。
        /// </summary>
        /// <param name="method">要推断泛型类型的泛型方法定义。</param>
        /// <param name="returnType">方法的实际返回类型,如果不存在则传入 <c>null</c>。</param>
        /// <param name="bounds">界限集集合。</param>
        /// <param name="isExplicit">类型检查时,如果考虑显式类型转换,则为 <c>true</c>;
        /// 否则只考虑隐式类型转换。</param>
        /// <returns>如果成功检查返回类型,则为 <c>true</c>;否则为 <c>false</c>。</returns>
        private static bool CheckReturnType(MethodBase method, Type returnType, TypeBounds bounds, bool isExplicit)
        {
            Contract.Requires(method != null && bounds != null);
            if (returnType == null)
            {
                return(true);
            }
            MethodInfo methodInfo = method as MethodInfo;

            if (methodInfo == null)
            {
                return(true);
            }
            Type type = methodInfo.ReturnType;

            if (type.ContainsGenericParameters)
            {
                // 对方法返回类型进行上限推断。
                return(bounds.TypeInferences(type, returnType, true));
            }
            return(returnType.IsConvertFrom(type, isExplicit));
        }
예제 #5
0
        /// <summary>
        /// 根据给定的方法实参类型数组推断泛型方法的泛型类型。
        /// </summary>
        /// <param name="method">要推断泛型类型的泛型方法定义。</param>
        /// <param name="returnType">方法的实际返回类型,如果不存在则传入 <c>null</c>。</param>
        /// <param name="types">方法实参类型数组。</param>
        /// <param name="options">方法参数信息的选项。</param>
        /// <returns>如果成功推断泛型方法的类型参数,则为推断结果;否则为 <c>null</c>。</returns>
        /// <remarks>得到的结果中,<see cref="MethodArgumentsInfo.ParamArrayType"/> 可能包含泛型类型参数。</remarks>
        internal static MethodArgumentsInfo GenericArgumentsInferences(this MethodBase method,
                                                                       Type returnType, Type[] types, MethodArgumentsOption options)
        {
            Contract.Requires(method != null && types != null);
            ParameterInfo[] parameters = method.GetParametersNoCopy();
            // 提取方法参数信息。
            types = types.Extend(parameters.Length, typeof(Missing));
            MethodArgumentsInfo result = MethodArgumentsInfo.GetInfo(method, types, options);

            if (result == null)
            {
                return(null);
            }
            // 对方法返回值进行推断。
            bool       isExplicit = options.HasFlag(MethodArgumentsOption.Explicit);
            TypeBounds bounds     = new TypeBounds(method.GetGenericArguments());

            if (!CheckReturnType(method, returnType, bounds, isExplicit))
            {
                return(null);
            }
            // 对方法固定参数进行推断。
            int paramLen = result.FixedArguments.Count;

            for (int i = 0; i < paramLen; i++)
            {
                Type paramType = parameters[i].ParameterType;
                Type argType   = result.FixedArguments[i];
                if (paramType.ContainsGenericParameters && argType != typeof(Missing) &&
                    !bounds.TypeInferences(paramType, argType))
                {
                    return(null);
                }
            }
            IList <Type> paramArgTypes = result.ParamArgumentTypes;

            if (result.ParamArrayType == null || paramArgTypes.Count == 0)
            {
                Type[] args = bounds.FixTypeArguments();
                if (args == null)
                {
                    return(null);
                }
                result.GenericArguments = args;
                return(result);
            }
            // 对 params 参数进行推断。
            Type paramElementType = result.ParamArrayType.GetElementType();
            int  paramArgCnt      = paramArgTypes.Count;

            if (paramArgCnt > 1)
            {
                // 多个实参对应一个形参,做多次类型推断。
                for (int i = 0; i < paramArgCnt; i++)
                {
                    if (paramArgTypes[i] != typeof(Missing) && !bounds.TypeInferences(paramElementType, paramArgTypes[i]))
                    {
                        return(null);
                    }
                }
                Type[] args = bounds.FixTypeArguments();
                if (args == null)
                {
                    return(null);
                }
                result.GenericArguments = args;
                return(result);
            }
            // 一个实参对应一个形参,需要判断是否需要展开 params 参数。
            TypeBounds newBounds = new TypeBounds(bounds);
            Type       type      = paramArgTypes[0];

            // 首先尝试对 paramArrayType 进行推断。
            if (type == typeof(Missing) || bounds.TypeInferences(result.ParamArrayType, type))
            {
                Type[] args = bounds.FixTypeArguments();
                if (args != null)
                {
                    // 推断成功的话,则无需展开 params 参数。
                    result.ClearParamArrayType();
                    result.GenericArguments = args;
                    return(result);
                }
            }
            // 然后尝试对 paramElementType 进行推断。
            if (newBounds.TypeInferences(paramElementType, type))
            {
                Type[] args = newBounds.FixTypeArguments();
                if (args == null)
                {
                    return(null);
                }
                result.GenericArguments = args;
                return(result);
            }
            return(null);
        }
예제 #6
0
파일: MethodExt.cs 프로젝트: GISwilson/Cyjb
 /// <summary>
 /// 检查方法的返回类型。
 /// </summary>
 /// <param name="method">要推断泛型类型的泛型方法定义。</param>
 /// <param name="returnType">方法的实际返回类型,如果不存在则传入 <c>null</c>。</param>
 /// <param name="bounds">界限集集合。</param>
 /// <param name="isExplicit">类型检查时,如果考虑显式类型转换,则为 <c>true</c>;
 /// 否则只考虑隐式类型转换。</param>
 /// <returns>如果成功检查返回类型,则为 <c>true</c>;否则为 <c>false</c>。</returns>
 private static bool CheckReturnType(MethodBase method, Type returnType, TypeBounds bounds, bool isExplicit)
 {
     Contract.Requires(method != null && bounds != null);
     if (returnType == null)
     {
         return true;
     }
     MethodInfo methodInfo = method as MethodInfo;
     if (methodInfo == null)
     {
         return true;
     }
     Type type = methodInfo.ReturnType;
     if (type.ContainsGenericParameters)
     {
         // 对方法返回类型进行上限推断。
         return bounds.TypeInferences(type, returnType, true);
     }
     return returnType.IsConvertFrom(type, isExplicit);
 }
예제 #7
0
파일: MethodExt.cs 프로젝트: GISwilson/Cyjb
 /// <summary>
 /// 根据给定的方法实参类型数组推断泛型方法的泛型类型。
 /// </summary>
 /// <param name="method">要推断泛型类型的泛型方法定义。</param>
 /// <param name="returnType">方法的实际返回类型,如果不存在则传入 <c>null</c>。</param>
 /// <param name="types">方法实参类型数组。</param>
 /// <param name="options">方法参数信息的选项。</param>
 /// <returns>如果成功推断泛型方法的类型参数,则为推断结果;否则为 <c>null</c>。</returns>
 /// <remarks>得到的结果中,<see cref="MethodArgumentsInfo.ParamArrayType"/> 可能包含泛型类型参数。</remarks>
 internal static MethodArgumentsInfo GenericArgumentsInferences(this MethodBase method,
     Type returnType, Type[] types, MethodArgumentsOption options)
 {
     Contract.Requires(method != null && types != null);
     ParameterInfo[] parameters = method.GetParametersNoCopy();
     // 提取方法参数信息。
     types = types.Extend(parameters.Length, typeof(Missing));
     MethodArgumentsInfo result = MethodArgumentsInfo.GetInfo(method, types, options);
     if (result == null)
     {
         return null;
     }
     // 对方法返回值进行推断。
     bool isExplicit = options.HasFlag(MethodArgumentsOption.Explicit);
     TypeBounds bounds = new TypeBounds(method.GetGenericArguments());
     if (!CheckReturnType(method, returnType, bounds, isExplicit))
     {
         return null;
     }
     // 对方法固定参数进行推断。
     int paramLen = result.FixedArguments.Count;
     for (int i = 0; i < paramLen; i++)
     {
         Type paramType = parameters[i].ParameterType;
         Type argType = result.FixedArguments[i];
         if (paramType.ContainsGenericParameters && argType != typeof(Missing) &&
             !bounds.TypeInferences(paramType, argType))
         {
             return null;
         }
     }
     IList<Type> paramArgTypes = result.ParamArgumentTypes;
     if (result.ParamArrayType == null || paramArgTypes.Count == 0)
     {
         Type[] args = bounds.FixTypeArguments();
         if (args == null)
         {
             return null;
         }
         result.GenericArguments = args;
         return result;
     }
     // 对 params 参数进行推断。
     Type paramElementType = result.ParamArrayType.GetElementType();
     int paramArgCnt = paramArgTypes.Count;
     if (paramArgCnt > 1)
     {
         // 多个实参对应一个形参,做多次类型推断。
         for (int i = 0; i < paramArgCnt; i++)
         {
             if (paramArgTypes[i] != typeof(Missing) && !bounds.TypeInferences(paramElementType, paramArgTypes[i]))
             {
                 return null;
             }
         }
         Type[] args = bounds.FixTypeArguments();
         if (args == null)
         {
             return null;
         }
         result.GenericArguments = args;
         return result;
     }
     // 一个实参对应一个形参,需要判断是否需要展开 params 参数。
     TypeBounds newBounds = new TypeBounds(bounds);
     Type type = paramArgTypes[0];
     // 首先尝试对 paramArrayType 进行推断。
     if (type == typeof(Missing) || bounds.TypeInferences(result.ParamArrayType, type))
     {
         Type[] args = bounds.FixTypeArguments();
         if (args != null)
         {
             // 推断成功的话,则无需展开 params 参数。
             result.ClearParamArrayType();
             result.GenericArguments = args;
             return result;
         }
     }
     // 然后尝试对 paramElementType 进行推断。
     if (newBounds.TypeInferences(paramElementType, type))
     {
         Type[] args = newBounds.FixTypeArguments();
         if (args == null)
         {
             return null;
         }
         result.GenericArguments = args;
         return result;
     }
     return null;
 }