0

I am trying to figure out a way that tells me if a certain type is an array/list/ienumerable/collection ... I dont care what kind of it is even CustomLists so something like

FooList<T> : IList<T>
FooList : IList

or stuff like that.

I kinda hoped that a simple type.IsArray would be enough but sadly this isnt the case.

I need a way to check if its one of the above types and then check what the underlying type is, and than cast it to a Indexed based collection, where I can loop through the entries.

For a simple array this is all I need:

if (obj.GetType().IsArray)
{
    var elementType = obj.GetType().GetElementType();
    if (elementType.IsPrimitive == false)
    {
        var array = (Array)obj;
    }
}

This should work for every collection, there could possible be.

Edit:

As recommended below, I should as/is to IEnumerable but with IEnumerable I have the problem that the I cannot set certain object inside this IEnumerable.

With array I have used the method array.SetValue(obj, index) which works fine.

When I loop threw the IEnumerable and try to set one entry like this:

var list = obj as IEnumarble;
if (list != null)
{
    foreach (var item in list)
    {
        item = new object();
    }
}

I am getting the following message:

Readonly local variable cannot be used as an assignment target.
Rand Random
  • 7,300
  • 10
  • 40
  • 88

2 Answers2

1

You can try to cast it with the as operator:

var enumerable = list as IEnumerable;
if (enumerable != null)
{
    foreach (object item in enumerable)
    { 
        // ...
    }
}

However, if you need to modify it you have to recreate it. For example by using a list which you fill in the loop. Then reassign it to the original variable.

Or you could check if the type is a ILIst in the first place (like an array or list), then you can use it`s indexer:

var ilist = list as IList;
if (ilist != null)
{
    for (int i = 0; i < ilist.Count; i++)
    {
        ilist[i] = "new value";
    }
}
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • How can I set a entry of the IEnumerable, I have used array.SetValue(obj, index) so far? – Rand Random Jan 07 '14 at 15:50
  • I am getting the following message doing this : "Readonly local variable cannot be used as an assignment target" – Rand Random Jan 07 '14 at 15:53
  • If I am not mistaken, this (... as IList) wouldnt work on a IEnumerable/IEnumerable or CustomLists that only implement one of those or? – Rand Random Jan 07 '14 at 16:03
  • Or is there maybe a way to make a writeable .GetEnumerator().Current, maybe a static extension that does the job? – Rand Random Jan 07 '14 at 16:20
  • No, you can't edit `Enumerator.Current`. `IEnumerable` provides read only and forward-only enumeration over a collection. That's it, nothing more. – MarcinJuraszek Jan 07 '14 at 16:34
0

IIRC, you could do a simple inheritence check for the enumerable interface via

if (FooList is IEnumerable)
    // We have a List

You can also use Linq and do a

if (FooList.ToList().Count > 1)
    // We have a List

But this would be rather unconventional.

Eisenhorn
  • 1,702
  • 1
  • 13
  • 20