Array, List, IEnumerable, CustomList class cast to one and iterate threw them

一曲冷凌霜 提交于 2019-12-11 23:14:06

问题


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.

回答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";
    }
}



回答2:


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.



来源:https://stackoverflow.com/questions/20975624/array-list-ienumerable-customlist-class-cast-to-one-and-iterate-threw-them

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!