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


      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 }
  • 相关阅读:
    0541-leetcode算法实现之反转字符串II-reverseStrII-python&golang实现
    helm 入门简介与安装(1)
    ubuntu18.04 netplan 设置dns,dns不生效
    服务器报错WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
    0344-leetcode算法实现之反转字符串-reverse-string-python&golang实现
    python os模块常用方法总结
    0076-leeycode算法实现之最小覆盖子串-minimum-window-substring-python&golang实现
    0904-leetcode算法实现之水果成篮-fruit-into-baskets-python&golang实现
    0209-leetcode算法实现之长度最小子数组-minimum-size-subarray-sum-python&golang实现
    0977-leetcode算法实现之有序数组的平方sqaure-of-a-sorted-array-python&golang实现
  • 原文地址:https://www.cnblogs.com/ziranquliu/p/4684991.html
Copyright © 2020-2023  润新知