Determine if object derives from collection type

前端 未结 11 2061
时光说笑
时光说笑 2021-02-05 04:53

I want to determine if a generic object type (\"T\") method type parameter is a collection type. I would typically be sending T through as a Generic.List but it could be any co

11条回答
  •  清歌不尽
    2021-02-05 05:33

    Personally I tend to use a method that I wrote myself, called TryGetInterfaceGenericParameters, which I posted below. Here is how to use it in your case:

    Example of use

    object currentObj = ...;  // get the object
    Type[] typeArguments;
    if (currentObj.GetType().TryGetInterfaceGenericParameters(typeof(IEnumerable<>), out typeArguments))
    {
        var innerType = typeArguments[0];
        // currentObj implements IEnumerable
    }
    else
    {
        // The type does not implement IEnumerable for any T
    }
    

    It is important to note here that you pass in typeof(IEnumerable<>), not typeof(IEnumerable) (which is an entirely different type) and also not typeof(IEnumerable) for any T (if you already know the T, you don’t need this method). Of course this works with any generic interface, e.g. you can use typeof(IDictionary<,>) as well (but not typeof(IDictionary)).

    Method source

    /// 
    ///     Determines whether the current type is or implements the specified generic interface, and determines that
    ///     interface's generic type parameters.
    /// 
    ///     The current type.
    /// 
    ///     A generic type definition for an interface, e.g. typeof(ICollection<>) or typeof(IDictionary<,>).
    /// 
    ///     Will receive an array containing the generic type parameters of the interface.
    /// 
    ///     True if the current type is or implements the specified generic interface.
    public static bool TryGetInterfaceGenericParameters(this Type type, Type @interface, out Type[] typeParameters)
    {
        typeParameters = null;
    
        if (type.IsGenericType && type.GetGenericTypeDefinition() == @interface)
        {
            typeParameters = type.GetGenericArguments();
            return true;
        }
    
        var implements = type.FindInterfaces((ty, obj) => ty.IsGenericType && ty.GetGenericTypeDefinition() == @interface, null).FirstOrDefault();
        if (implements == null)
            return false;
    
        typeParameters = implements.GetGenericArguments();
        return true;
    }
    

提交回复
热议问题