1 /// <summary> 2 /// 扩展类:检查一个类是否派生自某个泛型基类 3 /// </summary> 4 public static class ReflexionExtension 5 { 6 /// <summary> 7 /// 检查是否派生自某个泛型基类 8 /// </summary> 9 /// <param name="child">派生类</param> 10 /// <param name="parent">基类</param> 11 /// <returns></returns> 12 public static bool IsSubClassOfGeneric(this Type child, Type parent) 13 { 14 if (child == parent) 15 return false; 16 if (child.IsSubclassOf(parent)) 17 return true; 18 var parameters = parent.GetGenericArguments(); 19 var isParameterLessGeneric = !(parameters != null && parameters.Length > 0 && 20 ((parameters[0].Attributes & TypeAttributes.BeforeFieldInit) == TypeAttributes.BeforeFieldInit)); 21 while (child != null && child != typeof(object)) 22 { 23 var cur = GetFullTypeDefinition(child); 24 if (parent == cur || (isParameterLessGeneric && cur.GetInterfaces().Select(i => GetFullTypeDefinition(i)).Contains(GetFullTypeDefinition(parent)))) 25 return true; 26 else if (!isParameterLessGeneric) 27 if (GetFullTypeDefinition(parent) == cur && !cur.IsInterface) 28 { 29 if (VerifyGenericArguments(GetFullTypeDefinition(parent), cur)) 30 return true; 31 } 32 else 33 foreach (var item in child.GetInterfaces().Where(i => GetFullTypeDefinition(parent) == GetFullTypeDefinition(i))) 34 if (VerifyGenericArguments(parent, item)) 35 return true; 36 child = child.BaseType; 37 } 38 return false; 39 } 40 /// <summary> 41 /// 返回一个泛型类型 42 /// </summary> 43 /// <param name="type">子类</param> 44 /// <returns></returns> 45 private static Type GetFullTypeDefinition(Type type) 46 { 47 return type.IsGenericType ? type.GetGenericTypeDefinition() : type; 48 } 49 /// <summary> 50 /// 验证泛型参数是否一致 51 /// </summary> 52 /// <param name="parent">基类</param> 53 /// <param name="child">派生类</param> 54 /// <returns></returns> 55 private static bool VerifyGenericArguments(Type parent, Type child) 56 { 57 Type[] childArguments = child.GetGenericArguments(); 58 Type[] parentArguments = parent.GetGenericArguments(); 59 if (childArguments.Length == parentArguments.Length) 60 for (int i = 0; i < childArguments.Length; i++) 61 if (childArguments[i].Assembly == parentArguments[i].Assembly && childArguments[i].Name == parentArguments[i].Name && childArguments[i].Namespace == parentArguments[i].Namespace) 62 return true; 63 return false; 64 } 65 /// <summary> 66 /// Find out if a child type implements or inherits from the parent type. 67 /// The parent type can be an interface or a concrete class, generic or non-generic. 68 /// </summary> 69 /// <param name="child"></param> 70 /// <param name="parent"></param> 71 /// <returns></returns> 72 public static bool InheritsOrImplements2(this Type child, Type parent) 73 { 74 var currentChild = parent.IsGenericTypeDefinition && child.IsGenericType ? child.GetGenericTypeDefinition() : child; 75 while (currentChild != typeof(object)) 76 { 77 if (parent == currentChild || HasAnyInterfaces2(parent, currentChild)) 78 return true; 79 currentChild = currentChild.BaseType != null && parent.IsGenericTypeDefinition && currentChild.BaseType.IsGenericType 80 ? currentChild.BaseType.GetGenericTypeDefinition() 81 : currentChild.BaseType; 82 if (currentChild == null) 83 return false; 84 } 85 return false; 86 } 87 private static bool HasAnyInterfaces2(Type parent, Type child) 88 { 89 return child.GetInterfaces().Any(childInterface => 90 { 91 var currentInterface = parent.IsGenericTypeDefinition && childInterface.IsGenericType 92 ? childInterface.GetGenericTypeDefinition() 93 : childInterface; 94 return currentInterface == parent; 95 }); 96 } 97 /// <summary> 98 /// Checks whether this type has the specified definition in its ancestry. 99 /// </summary> 100 public static bool HasGenericDefinition(this Type type, Type definition) 101 { 102 return GetTypeWithGenericDefinition(type, definition) != null; 103 } 104 /// <summary> 105 /// Returns the actual type implementing the specified definition from the 106 /// ancestry of the type, if available. Else, null. 107 /// </summary> 108 public static Type GetTypeWithGenericDefinition(this Type type, Type definition) 109 { 110 if (type == null) 111 throw new ArgumentNullException("type"); 112 if (definition == null) 113 throw new ArgumentNullException("definition"); 114 if (!definition.IsGenericTypeDefinition) 115 throw new ArgumentException( 116 "The definition needs to be a GenericTypeDefinition", "definition"); 117 if (definition.IsInterface) 118 foreach (var interfaceType in type.GetInterfaces()) 119 if (interfaceType.IsGenericType 120 && interfaceType.GetGenericTypeDefinition() == definition) 121 return interfaceType; 122 for (Type t = type; t != null; t = t.BaseType) 123 if (t.IsGenericType && t.GetGenericTypeDefinition() == definition) 124 return t; 125 return null; 126 } 127 static bool IsSubclassOfRawGeneric2(Type generic, Type toCheck) 128 { 129 while (toCheck != typeof(object)) 130 { 131 var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck; 132 if (cur.IsGenericType && generic.GetGenericTypeDefinition() == cur.GetGenericTypeDefinition()) 133 { 134 return true; 135 } 136 toCheck = toCheck.BaseType; 137 } 138 return false; 139 } 140 static bool IsSubclassOfRawGeneric1(Type generic, Type toCheck) 141 { 142 while (toCheck != null && toCheck != typeof(object)) 143 { 144 var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck; 145 if (generic == cur) 146 { 147 return true; 148 } 149 toCheck = toCheck.BaseType; 150 } 151 return false; 152 } 153 /// <summary> 154 /// 深度查找基类是否派生自某个泛型类 155 /// </summary> 156 /// <param name="typeToCheck"></param> 157 /// <param name="genericType"></param> 158 /// <returns></returns> 159 public static bool IsTypeDerivedFromGenericType(this Type typeToCheck, Type genericType) 160 { 161 if (typeToCheck == typeof(object)) 162 { 163 return false; 164 } 165 else if (typeToCheck == null) 166 { 167 return false; 168 } 169 else if (typeToCheck.IsGenericType && typeToCheck.GetGenericTypeDefinition() == genericType) 170 { 171 return true; 172 } 173 else 174 { 175 return IsTypeDerivedFromGenericType(typeToCheck.BaseType, genericType); 176 } 177 } 178 /// <summary> 179 /// 检查一个对象是从一个特定的类型派生创造 180 /// </summary> 181 /// <param name="t"></param> 182 /// <param name="typeToCompare"></param> 183 /// <returns></returns> 184 internal static bool IsDerivativeOf(this Type t, Type typeToCompare) 185 { 186 if (t == null) throw new NullReferenceException(); 187 if (t.BaseType == null) return false; 188 if (t.BaseType == typeToCompare) return true; 189 else return t.BaseType.IsDerivativeOf(typeToCompare); 190 } 191 public static bool InheritsOrImplements1(this Type child, Type parent) 192 { 193 parent = ResolveGenericTypeDefinition(parent); 194 var currentChild = child.IsGenericType 195 ? child.GetGenericTypeDefinition() 196 : child; 197 while (currentChild != typeof(object)) 198 { 199 if (parent == currentChild || HasAnyInterfaces1(parent, currentChild)) 200 return true; 201 currentChild = currentChild.BaseType != null 202 && currentChild.BaseType.IsGenericType 203 ? currentChild.BaseType.GetGenericTypeDefinition() 204 : currentChild.BaseType; 205 if (currentChild == null) 206 return false; 207 } 208 return false; 209 } 210 private static bool HasAnyInterfaces1(Type parent, Type child) 211 { 212 return child.GetInterfaces() 213 .Any(childInterface => 214 { 215 var currentInterface = childInterface.IsGenericType 216 ? childInterface.GetGenericTypeDefinition() 217 : childInterface; 218 return currentInterface == parent; 219 }); 220 } 221 private static Type ResolveGenericTypeDefinition(Type parent) 222 { 223 var shouldUseGenericType = true; 224 if (parent.IsGenericType && parent.GetGenericTypeDefinition() != parent) 225 shouldUseGenericType = false; 226 if (parent.IsGenericType && shouldUseGenericType) 227 parent = parent.GetGenericTypeDefinition(); 228 return parent; 229 } 230 231 }