/// <summary> /// 根据给定的用户定义转换获取最合适的转换。 /// </summary> /// <param name="method">要测试的用户定义转换。</param> /// <param name="exactSource">当前最合适的源类型。</param> /// <param name="exactTarget">当前最合适的目标类型。</param> /// <param name="uniqueMethod">最合适的转换。</param> private static void GetBestConversion(ConversionMethod method, ref Type exactSource, ref Type exactTarget, UniqueValue <ConversionMethod> uniqueMethod) { if (exactSource != method.SourceType) { if (exactSource != null && method.SourceType.IsAssignableFrom(exactSource)) { return; } else { exactSource = method.SourceType; uniqueMethod.Reset(); } } if (exactTarget != method.TargetType) { if (exactTarget != null && exactTarget.IsAssignableFrom(method.TargetType)) { return; } else { exactTarget = method.TargetType; uniqueMethod.Reset(); } } uniqueMethod.Value = method; }
/// <summary> /// 返回从源类型到目标类型的用户定义的显式转换方法。 /// 该转换方法的参数与源类型和目标类型并不一定完全相同,但保证存在标准显式转换。 /// </summary> /// <param name="sourceType">要获取用户定义的转换方法的源类型。</param> /// <param name="targetType">要获取用户定义的转换方法的目标类型。</param> /// <returns>如果存在从源类型到目标类型的用户定义的显式转换方法,则返回该方法; /// 否则返回 <c>null</c>。</returns> public static ConversionMethod GetExplicitConversion(Type sourceType, Type targetType) { Type exactSource = null, exactTarget = null; UniqueValue <ConversionMethod> method = new UniqueValue <ConversionMethod>(); Conversion conv = GetTypeConversions(sourceType.GetNonNullableType()); for (int i = conv.ConvertToIndex; i < conv.Methods.Length; i++) { ConversionMethod m = conv.Methods[i]; if (targetType.IsStandardExplicitFrom(m.TargetType)) { GetBestConversion(m, ref exactSource, ref exactTarget, method); } } conv = GetTypeConversions(targetType.GetNonNullableType()); for (int i = Conversion.ConvertFromIndex; i < conv.ConvertToIndex; i++) { ConversionMethod m = conv.Methods[i]; if (m.SourceType.IsStandardExplicitFrom(sourceType)) { GetBestConversion(m, ref exactSource, ref exactTarget, method); } } if (method.IsUnique) { return(method.Value); } return(null); }
/// <summary> /// 确定当前的开放泛型类型的实例是否可以从指定 <see cref="System.Type"/> 的实例唯一分配, /// 并返回唯一相应的封闭泛型类型。 /// </summary> /// <param name="type">要判断的开放泛型类型。</param> /// <param name="fromType">要与当前类型进行比较的类型。</param> /// <param name="closedType">如果可以唯一分配到开放泛型类型,则返回相应的封闭泛型类型; /// 否则返回 <c>null</c>。</param> /// <returns>如果当前的开放泛型类型可以从 <paramref name="fromType"/> 的实例唯一分配, /// 则为 <c>true</c>;否则为 <c>false</c>。</returns> /// <example> /// 下面是 <see cref="UniqueOpenGenericIsAssignableFrom(Type,Type,out Type)"/> 方法的简单示例: /// <code> /// Type type; /// Console.WriteLine(typeof(IEnumerable{}).UniqueOpenGenericIsAssignableFrom( /// typeof(List}int}), out type)); /// Console.WriteLine(type); /// Console.WriteLine(typeof(IEnumerable{}).UniqueOpenGenericIsAssignableFrom( /// typeof(TestClass))); /// class TestClass : IEnumerable{int}, IEnumerable{long} { } /// // 示例输出: /// // True /// // System.Collections.Generic.IEnumerable`1[System.Int32] /// // False /// </code> /// </example> /// <remarks> /// <para>如果一个类将一个泛型接口实现了多次,则不满足唯一实现,会返回 <c>false</c>。 /// 仅当实现了一次时,才会返回 <c>true</c>,以及相应的封闭泛型类型。</para> /// <para>关于判断是否可以分配到开放泛型类型的算法可以参考我的博客文章 /// <see href="http://www.cnblogs.com/JFToolKit/archive/p/TypeAssignableFrom.html"> /// 《C# 判断类型间能否隐式或强制类型转换,以及开放泛型类型转换》</see>。</para></remarks> /// <seealso href="http://www.cnblogs.com/JFToolKit/archive/p/TypeAssignableFrom.html"> /// 《C# 判断类型间能否隐式或强制类型转换,以及开放泛型类型转换》</seealso> /// <overloads> /// <summary> /// 确定当前的开放泛型类型的实例是否可以从指定 <see cref="System.Type"/> 的实例唯一分配。 /// </summary> /// </overloads> public static bool UniqueOpenGenericIsAssignableFrom(this Type type, Type fromType, out Type closedType) { if (type != null && fromType != null && type.IsGenericTypeDefinition) { if (type.IsInterface == fromType.IsInterface) { if (type.InInheritanceChain(fromType, out closedType)) { return(true); } } if (type.IsInterface) { // 查找唯一实现的接口。 Type[] interfaces = fromType.GetInterfaces(); UniqueValue <Type> unique = new UniqueValue <Type>(); for (int i = 0; i < interfaces.Length; i++) { if (type.InInheritanceChain(interfaces[i], out closedType)) { unique.Value = closedType; if (unique.IsAmbig) { return(false); } } } if (unique.IsUnique) { closedType = unique.Value; return(true); } } } closedType = null; return(false); }
/// <summary> /// 固定当前界限集所限定的类型参数。 /// </summary> /// <returns>如果成功固定当前界限集的的类型参数,则为类型参数; /// 如果固定失败,则为 <c>null</c>。</returns> public Type FixTypeArg() { Type result = null; if (exactBound == null) { List <Type> list = new List <Type>(new HashSet <Type>(lowerBounds.Concat(upperBounds)) .Where(type => this.CanFixed(type))); if (list.Count == 0) { // 没有找到合适的推断结果。 return(null); } else if (list.Count == 1) { // 找到唯一的推断结果。 result = list[0]; } else { // 进一步进行推断。 UniqueValue <Type> uType = new UniqueValue <Type>(); int cnt = list.Count; for (int j = 0; j < cnt; j++) { int k = 0; for (; k < cnt; k++) { if (k == j) { continue; } if (!list[j].IsImplicitFrom(list[k])) { break; } } if (k == cnt) { uType.Value = list[j]; } } if (uType.IsUnique) { result = uType.Value; } else { // 推断失败。 return(null); } } } else { result = exactBound; } // 判断引用类型约束。 if (ReferenceType && result.IsValueType) { return(null); } return(result); }