检查一个类是否派生自某个泛型基类

  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 }
原文地址:https://www.cnblogs.com/ziranquliu/p/4684991.html