114
public bool IsList(object value)
    {
        Type type = value.GetType();
        // Check if type is a generic list of any type
    }

What's the best way to check if the given object is a list, or can be cast to a list?

  • Maybe you find answer here http://stackoverflow.com/questions/755200/how-do-i-detect-that-an-object-is-a-generic-collection-and-what-types-it-contain – Maksim Kondratyuk Apr 27 '09 at 16:10

9 Answers9

151

For you guys that enjoy the use of extension methods:

public static bool IsGenericList(this object o)
{
    var oType = o.GetType();
    return (oType.IsGenericType && (oType.GetGenericTypeDefinition() == typeof(List<>)));
}

So, we could do:

if(o.IsGenericList())
{
 //...
}
FirstHorizon
  • 118
  • 1
  • 11
Victor Rodrigues
  • 11,353
  • 23
  • 75
  • 107
  • 5
    For .Net Core this needs to be modified slightly to `return oType.GetTypeInfo().IsGenericType && oType.GetGenericTypeDefinition() == typeof(List<>);` – Rob L Jun 10 '17 at 11:28
  • Works like a charm! If you only have the type not the object this will work for you! Thanks!! – gatsby Apr 05 '18 at 15:31
  • Would checking for `IList<>` instead be safer? – nl-x Dec 12 '19 at 18:09
118
using System.Collections;

if(value is IList && value.GetType().IsGenericType) {

}
Bartho Bernsmann
  • 2,393
  • 1
  • 25
  • 34
James Couvares
  • 1,743
  • 1
  • 16
  • 15
  • 6
    This does not work - I get the following exception - value is IList Using the generic type 'System.Collections.Generic.IList' requires '1' type arguments –  Apr 27 '09 at 16:38
  • 20
    You need to add using System.Collections; on top of your source file. The IList interface I suggested is NOT the generic version (hence the second check) – James Couvares Apr 27 '09 at 16:41
  • 1
    You're right. This works like a charm. I was testing this in my Watch window and forgot all about the missing namespace. I like this solution better, very simple –  Apr 27 '09 at 16:51
  • 3
    This doesn't work. I would guess in 4.0 IList != IList? Anyway, I had to check if it was generic and IEnumerable, and then check for the existence of the property I wanted to check, "Count". I suppose this weakness is partly why WCF turns all of your List's into T[]. –  May 09 '13 at 20:55
  • @user1086498 this is not a weakness of WCF. if you look at your service Reference advanced tab you can select Generic list instead of array – Lawrence Thurman Dec 17 '15 at 23:01
  • 1
    @Edza Incorrect. This *usually* works since `List` and `ObservableCollection` implement `IList`. – HappyNomad Jul 27 '16 at 22:16
  • 1
    That is actually not accurate solution. `Foo : IList != IList` – Kovpaev Alexey Jul 29 '16 at 08:50
17
 bool isList = o.GetType().IsGenericType 
                && o.GetType().GetGenericTypeDefinition() == typeof(IList<>));
Eoin Campbell
  • 43,500
  • 17
  • 101
  • 157
8

Here's an implementation that works in .NET Standard, and works against interfaces:

    public static bool ImplementsGenericInterface(this Type type, Type interfaceType)
    {
        return type
            .GetTypeInfo()
            .ImplementedInterfaces
            .Any(x => x.GetTypeInfo().IsGenericType && x.GetGenericTypeDefinition() == interfaceType);
    }

And here are the tests (xunit):

    [Fact]
    public void ImplementsGenericInterface_List_IsValidInterfaceTypes()
    {
        var list = new List<string>();
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IList<>)));
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IEnumerable<>)));
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IReadOnlyList<>)));
    }

    [Fact]
    public void ImplementsGenericInterface_List_IsNotInvalidInterfaceTypes()
    {
        var list = new List<string>();
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(string)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(IDictionary<,>)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(IComparable<>)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(DateTime)));
    }
Jeff Siemens
  • 81
  • 1
  • 2
7
public bool IsList(object value) {
    return value is IList 
        || IsGenericList(value);
}

public bool IsGenericList(object value) {
    var type = value.GetType();
    return type.IsGenericType
        && typeof(List<>) == type.GetGenericTypeDefinition();
}
Atif Aziz
  • 36,108
  • 16
  • 64
  • 74
6

Based on Victor Rodrigues' answer, we can devise another method for generics. In fact, the original solution can be reduced to only two lines:

public static bool IsGenericList(this object Value)
{
    var t = Value.GetType();
    return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<>);
}

public static bool IsGenericList<T>(this object Value)
{
    var t = Value.GetType();
    return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<T>);
}
5

I'm using the following code:

public bool IsList(Type type) => type.IsGenericType && (
            (type.GetGenericTypeDefinition() == typeof(List<>))
            || (type.GetGenericTypeDefinition() == typeof(IList<>))
            );
Gaspa79
  • 5,488
  • 4
  • 40
  • 63
Yashar Aliabbasi
  • 2,663
  • 1
  • 23
  • 35
5
if(value is IList && value.GetType().GetGenericArguments().Length > 0)
{

}
BFree
  • 102,548
  • 21
  • 159
  • 201
1

Probably the best way would be to do something like this:

IList list = value as IList;

if (list != null)
{
    // use list in here
}

This will give you maximum flexibility and also allow you to work with many different types that implement the IList interface.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635