2

我有一个object.

这个对象正在铸造一个Items Container(我不知道什么项目,但我可以检查)。

但是有没有任何代码可以帮助我找到它包含多少项目?

我是说

 object[] arrObj = new object[2] {1, 2};
 object o = (object)arrObj;

在这种情况下arrObj是一个数组,所以我可以检查:

((Array)o).Length//2

但是如果我有另外两个呢?

 ArrayList al = new ArrayList(2);
           al.Add(1);
           al.Add(2);
 object o = (object)al ;

 List<object> lst= new List<object>(2);
 object o = (object)lst;

是否有任何通用代码可以帮助我找到这个铸造对象中有多少项目(o在这个示例中)?

当然我可以检查if (o is ...) { },但我正在寻找更通用的代码。

4

3 回答 3

4

您可以强制转换为每个容器实现的接口:IEnumerable. 但是,为了提高性能,最好先尝试IEnumerable<T>

var count = -1;
var enumerable = lst as IEnumerable<object>;
if(enumerable != null)
    count = enumerable.Count();
else
{
    var nonGenericEnumerable = lst as IEnumerable;
    count = nonGenericEnumerable.Cast<object>().Count();
}

为了Count()可用,您需要添加using System.Linq;到您的 .cs 文件中。

请注意,此代码有一个很大的优势:如果集合实现ICollection<T>- 类似List<T>或强类型的引用类型数组 - 此代码在 O(1)中执行[假设在 O(1) 中执行的具体实现ICollection<T>.Count]。只有当它不喜欢ArrayList或强类型的值类型数组时,此代码才会在 O(n) 中执行,此外,它会在值类型数组的情况下将项目装箱。

于 2013-02-01T14:10:23.003 回答
3

你可以使用 linq。

var count = ((IEnumerable)o).Cast<object>().Count();

确保该类型o具有实现IEnumerable,并且您using System.Linq在文件的顶部具有。

于 2013-02-01T14:08:26.933 回答
2

那么它可以实现的最基本的接口是IEnumerable. 不幸的是,即使Enumerable.Count从 LINQ 实现IEnumerable<T>,但您可以轻松编写自己的:

public static int Count(IEnumerable sequence)
{
    // Shortcut for any ICollection implementation
    var collection = sequence as ICollection;
    if (collection != null)
    {
        return collection.Count;
    }

    var iterator = sequence.GetEnumerator();
    try
    {
        int count = 0;
        while (iterator.MoveNext())
        {
            count++;
        }
        return count;
    }
    finally
    {
        IDisposable disposable = iterator as IDisposable;
        if (disposable != null)
        {
            disposable.Dispose();
        }
    }
}

请注意,这基本上等同于:

int count = 0;
foreach (object item in sequence)
{
    count++;
}

...除了因为它从不使用,如果你的容器实际上是一个例子Current,它就不需要做任何装箱。int[]

调用它:

var sequence = container as IEnumerable;
if (sequence != null) 
{
    int count = Count(sequence);
    // Use the count
}

值得注意的是,避免装箱实际上是一种微优化:它不太可能真的很重要。但是你可以用这种方法做一次,然后到处利用它。

于 2013-02-01T14:10:29.867 回答