如何从作为对象的IList<>中获取项目计数?

13

在一个方法中,我获取了一个对象

在某些情况下,这个对象可能是一个“something”的IList(我无法控制这个“something”)。

我正在尝试:

  1. 确定这个对象是一个IList(of something)
  2. 对象转换为一个“IList<something>”,以便能够从中获取Count

目前,我被卡住了,正在寻找思路。


你只需要 Count 吗?如果是这样,你不需要它成为一个 IList<T>,一个简单的 IEnumerable 就可以了。 - AakashM
是的,Count 就是我想要的。但是我在 IEnumerable 中找不到任何 Count - remio
4个回答

23
你可以使用 is 来检查你的object是否实现了IList接口。
然后你可以将你的object强制转换成IList以获得计数。
object myObject = new List<string>();

// check if myObject implements IList
if (myObject  is IList)
{
   int listCount = ((IList)myObject).Count;
}

啊,太好了,这就是我想要的。我一直在寻找 IList<T> 是一个 IList。但是由于 List<T>Collection<T> 都是 IList,所以这已经足够了。谢谢。 - remio

4
if (obj is ICollection)
{
    var count = ((ICollection)obj).Count;
}

1
将使用更多类型的集合,强制转换为IEnumerable并读取.Count()而不是.Count,这样就可以处理更多的集合类型。 - Danny Varod
1
@DannyVarod 但是 IEnumerable.Count() 的风险在于需要枚举集合以计算其项数。 - phoog
1
根据集合的实际类型而定。对于列表来说,它不会。 - Danny Varod
@remio 其实,我刚刚在看ILSpy,IEnumerable方法对于你的用例不起作用。Count()扩展方法是针对IEnumerable<T>而不是IEnumerable的,因此在调用Count()之前,你仍然需要确定集合成员的类型。 - phoog
此外,如果您按照AakashM的建议调用Cast<object>,则不再直接计算列表成员数量;而是从转换迭代器中获取它们,该迭代器无法访问包装对象的Count属性。 - phoog
显示剩余3条评论

1
        object o = new int[] { 1, 2, 3 };

        //...

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

这会打印出3,因为int[]是一个IList。


0

既然你只需要计数,那么你可以利用实现了 IList<T> 接口的任何对象也都实现了 IEnumerable 接口这一事实;而且在 System.Linq.Enumerable 中还有一个扩展方法,可以返回任何(泛型)序列的计数:

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

调用 Cast 是因为默认情况下 非泛型的 IEnumerable 上没有 Count 方法


啊,我理解了!但是我需要预计这个实现会对性能产生影响吗? - remio
@remio 是的,你需要。因为你调用了Cast<object>,所以你将无法从基础列表的Count属性中获益,因此你确实需要遍历整个列表以计算项目数。此外,如果列表的元素是值类型,由于转换为object,你将不得不对它们进行装箱。 - phoog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接