This is the start of a new set of functionality intended to ease the pain of working with generic types through reflection. Also, it is a good playground for getting to know generics (and the idea of thinking about types as variable).

  1. GetInterfaces

    /// <summary>
    /// Gets the interfaces for the given target type.
    /// </summary>
    /// <param name="target">The target type.</param>
    /// <param name="declaredOnly">true to only search interfaces declared on the definition of the type itself (i.e. NOT inherited).</param>
    /// <returns>The requested interface types.</returns>
    public static IEnumerable<Type> GetInterfaces( this Type target, bool declaredOnly = false ) {
       return declaredOnly
                ? target.GetInterfaces().Except((target.BaseType ?? typeof(object)).GetInterfaces().ToList())
                : target.GetInterfaces();
    }
    

    This function gets the interfaces that are supported by the target type. It defaults to retrieving all the interfaces implemented up the inheritance chain, unless declaredOnly is true (in which case it only returns interfaces declared on the target type definition – i.e. it excludes all interfaces declared further up the chain).

    Example:

    obj.GetType().GetInterfaces() OR obj.GetType().GetInterfaces(declaredOnly: true)
    

  2. Matches

    /// <summary>
    /// Determines if the given target type matches the specified template type.
    /// </summary>
    /// <param name="target">The target type.</param>
    /// <param name="template">The teamplate type to match.</param>
    /// <returns>true if the given type matches the given template type, otherwise false.</returns>
    /// <remarks>Supports generic type definitions for <paramref name="template"/>.</remarks>
    public static bool Matches( this Type target, Type template ) {
       return template.IsGenericTypeDefinition
                ? (target.IsGenericTypeDefinition &amp;&amp; target == template)
                  || (target.IsGenericType &amp;&amp; target.GetGenericTypeDefinition() == template)
                : (target == template);
    }
    

    This function looks for an exact match between the target type and a supplied template type.

    Example:

    obj.GetType().Matches(typeof(MyType))
    
    • The following will all resolve to true:
      typeof(string).Matches(typeof(string));
      typeof(List<string>).Matches(typeof(List<string>));
      typeof(List<string>).Matches(typeof(List<>));
      typeof(List<>).Matches(typeof(List<>));
      

  3. Implements

    /// <summary>
    /// Determines if the given target type implements the specified interface type.
    /// </summary>
    /// <param name="target">The target type.</param>
    /// <param name="interfaceType">The interface type to search for.</param>
    /// <param name="declaredOnly">true to only search interfaces declared on the definition of the type itself (i.e. NOT inherited).</param>
    /// <returns>true if the given type implements the given interface type, otherwise false.</returns>
    /// <remarks>Supports generic type definitions for <paramref name="interfaceType"/>.</remarks>
    public static bool Implements( this Type target, Type interfaceType, bool declaredOnly = false ) {
       return target.GetInterfaces(declaredOnly)
          .Any(t => t.Matches(interfaceType));
    }
    

    Based on GetInterfaces and Matches (1 and 2 above), this function will return true if the given target has any interfaces matching the specified interfaceType within the scope indicated by declaredOnly.

    Example:

    obj.GetType().Implements(typeof(IMyType)) OR obj.GetType().Implements(typeof(IMyType), declaredOnly: true)
    

  4. Extends

    /// <summary>
    /// Determines if the given target type extends the specified base type.
    /// </summary>
    /// <param name="target">The target type.</param>
    /// <param name="baseType">The base type to search for.</param>
    /// <param name="immediate">true to only check the immediate base type (i.e. NOT search up the inheritance chain).</param>
    /// <returns>true if the given type extends the given base type, otherwise false.</returns>
    /// <remarks>Supports generic type definitions for <paramref name="baseType"/>.</remarks>
    public static bool Extends( this Type target, Type baseType, bool immediate = false ) {
       Type b;
       do {
          b = target.BaseType;
          if( b != null &amp;&amp; b.Matches(baseType) ) {
             return true;
          }
       } while( !immediate &amp;&amp; b != null &amp;&amp; b != typeof(object) );
       return false;
    }
    

    Similar to Implements, this will return true if target has a base type that Matches to the given baseType. If immediate is true then only the immediate base type is checked (otherwise it searches all the way up the inheritance chain).

    Example:

    obj.GetType().Extends(typeof(MyBaseType)) OR obj.GetType().Extends(typeof(MyBaseType), immediate: true)
    

  5. IsDecoratedWith

    /// <summary>
    /// Determines if the given target type is decorated with the specified attribute type.
    /// </summary>
    /// <param name="target">The target type.</param>
    /// <param name="attributeType">The attribute type to search for.</param>
    /// <param name="inherit">true to search the target type's inheritance chain, otherwise false.</param>
    /// <returns>true if the given target type is decorated with the specified attribute type, otherwise false.</returns>
    public static bool IsDecoratedWith( this Type target, Type attributeType, bool inherit = false ) {
       return target.GetCustomAttributes(attributeType, inherit).Length != 0;
    }
    

    This function will simply check whether the target type has an attribute decoration of the type specified by attributeType. If inherit is true it will search up the inheritance chain.

    Example:

    obj.GetType().IsDecoratedWith(typeof(MyAttribute)) OR obj.GetType().IsDecoratedWith(typeof(MyAttribute), inherit: true)
    

  6. IsGenericWithArguments

    /// <summary>
    /// Determines if the given target type is a generic type with the specified generic type arguments.
    /// </summary>
    /// <param name="target">The target type.</param>
    /// <param name="typeArguments">The generic type arguments to check for.</param>
    /// <returns>true if the target type is a generic type with the given generic type arguments.</returns>
    public static bool IsGenericWithArguments( this Type target, params Type[] typeArguments ) {
       if( !target.IsGenericType ) {
          return false;
       }
       Type[] args = target.GetGenericArguments();
       if( typeArguments.Length != args.Length ) {
          return false;
       }
       for( int n = 0; n < args.Length; n++ ) {
          if( args&#91;n&#93;.Matches(typeArguments&#91;n&#93;) ) {
             return false;
          }
       }
       return true;
    }
    &#91;/sourcecode&#93;
    
    This function checks whether the <code>target</code> type is a generic type with generic type arguments matching those supplied in <code>typeArguments</code>.
    
    <h3>Example:</h3>
    
    obj.GetType().IsGenericWithArguments(typeof(int), typeof(string))
    
    • Will evaluate to true for all of the following:

      typeof(IEnumerable<string>).IsGenericWithArguments(typeof(string));
      typeof(List<string>).IsGenericWithArguments(typeof(string));
      typeof(Dictionary<int, string>).IsGenericWithArguments(typeof(int), typeof(string));
      

Get the code here … Enjoy!