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 }