How to get the items count from an IList<> got as an object?
Asked Answered
C

4

14

In a method, I get an object.

In some situation, this object can be an IList of "something" (I have no control over this "something").

I am trying to:

  1. Identify that this object is an IList (of something)
  2. Cast the object into an "IList<something>" to be able to get the Count from it.

For now, I am stuck and looking for ideas.

Chiachiack answered 25/1, 2012 at 9:29 Comment(2)
Is the Count all you want? If so, you don't need it to be an IList<T>, a simple IEnumerable will do.Atherton
Yes, Count is all that I want. However, I can't see any Count in IEnumerable?Chiachiack
F
23

You can check if your object implements IList using is.

Then you can cast your object to IList to get the count.

object myObject = new List<string>();

// check if myObject implements IList
if (myObject  is IList)
{
   int listCount = ((IList)myObject).Count;
}
Faustina answered 25/1, 2012 at 9:34 Comment(1)
Ah, great, this is what I missed. I was looking for IList<T> being an IList. But as List<T> and Collection<T> are ILists, This is enough for me. Thanks.Chiachiack
E
3
if (obj is ICollection)
{
    var count = ((ICollection)obj).Count;
}
Evzone answered 25/1, 2012 at 9:34 Comment(8)
Thanks for your answer. Is there a benefit of casting into ICollection over casting into IList?Chiachiack
Will work with more types of collections, casting to IEnumerable and reading .Count() instead of .Count will work with even more.Evzone
@DannyVarod but IEnumerable.Count() risks enumerating the collection in order to count its items.Corry
Depends on actual type of collection. For lists it won't.Evzone
@phoog, This is exactly what I was suspicious about, but as it won't be the case for lists according to DannyVarod' statemtent, it seems to be a good compromise to be able to handle ost of the situations. Developers "just" need to be aware of it.Chiachiack
@Chiachiack Actually, I was just looking at ILSpy, and the IEnumerable approach won't work for your use case. The Count() extension method is for IEnumerable<T>, not IEnumerable, so you're still left with the problem of determining the type of the collection's members before you can call Count().Corry
@Chiachiack Additionally, if you call Cast<object> as suggested by AakashM, you're no longer counting the members of the list directly; you're getting them from the cast iterator, which doesn't give access to the Count property of the wrapped object.Corry
You can determine generic type parameter then use that for a more specific cast, however, that would be an overkill for this simple situation. That is why I suggested ICollection at first.Evzone
C
1
        object o = new int[] { 1, 2, 3 };

        //...

        if (o is IList)
        {
            IList l = o as IList;
            Console.WriteLine(l.Count);
        }

This prints 3, because int[] is a IList.

Cadmarr answered 25/1, 2012 at 9:37 Comment(0)
A
0

Since all you want is the count, you can use the fact that anything that implements IList<T> also implements IEnumerable; and furthermore there is an extension method in System.Linq.Enumerable that returns the count of any (generic) sequence:

var ienumerable = inputObject as IEnumerable;
if (ienumerable != null)
{
    var count = ienumerable.Cast<object>().Count();
}

The call to Cast is because out of the box there isn't a Count on non-generic IEnumerable.

Atherton answered 25/1, 2012 at 9:49 Comment(2)
Ah, yes, I get it! But would I have to expect performance impacts with this implementation?Chiachiack
@Chiachiack yes, you would. Because you're calling Cast<object>, you will not be able to benefit from the underlying list's Count property, so you will indeed iterate the entire list in order to count the items. Furthermore, if the list's elements are of a value type, you'll have to box each of them because of the cast to object.Corry

© 2022 - 2024 — McMap. All rights reserved.