Arraylist,IEnumerable,自定义列表类强制转换为一个并迭代抛出它们

时间:2014-01-07 15:34:51

标签: c# arrays collections casting ienumerable

我试图弄清楚一种方式告诉我某个类型是否是一个数组/列表/ ienumerable /集合...我不关心它甚至是什么类型的CustomLists所以像

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

或类似的东西。

我有点希望一个简单的类型.IsArray就够了但遗憾的是这不是这样的。

我需要一种方法来检查它是否是上述类型之一,然后检查基础类型是什么,然后将其转换为基于索引的集合,我可以在其中循环访问条目。

对于一个简单的数组,这就是我所需要的:

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

这应该适用于每个集合,有可能。

修改

正如下面的推荐,我应该/是IEnumerable,但是使用IEnumerable我有问题,我不能在这个IEnumerable中设置某个对象。

使用数组我已经使用了方法array.SetValue(obj,index),它可以正常工作。

当我循环抛出IEnumerable并尝试设置一个这样的条目:

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

我收到以下消息:

Readonly local variable cannot be used as an assignment target.

2 个答案:

答案 0 :(得分:1)

您可以尝试使用as运算符:

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

但是,如果您需要修改它,则必须重新创建它。例如,通过使用填充循环的列表。然后将其重新分配给原始变量。

或者您可以首先检查类型是否为ILIst(如数组或列表),然后您可以使用它作为索引器:

var ilist = list as IList;
if (ilist != null)
{
    for (int i = 0; i < ilist.Count; i++)
    {
        ilist[i] = "new value";
    }
}

答案 1 :(得分:0)

IIRC,您可以通过

对可消除的接口进行简单的继承检查
if (FooList is IEnumerable)
    // We have a List

您也可以使用Linq并执行

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

但这将是非常规的。