我有object
。
此对象正在投射Items Container
(我不知道哪些项目,但我可以查看)。
但有没有任何代码可以帮助我找到它包含多少项目?
我的意思是
object[] arrObj = new object[2] {1, 2};
object o = (object)arrObj;
在这种情况下,arrObj
是一个数组,所以我可以检查:
((Array)o).Length
// 2
但是如果我有其他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 ...) { }
,但我正在寻找更通用的代码。
答案 0 :(得分: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)中执行[假设ICollection<T>.Count
的具体实现在O(1)] 中执行。只有当它没有 - 比如ArrayList
或强类型的值类型数组 - 这个代码才会在O(n)中执行,此外,它会在值类型数组的情况下对项进行打包。
答案 1 :(得分:3)
你可以使用linq。
var count = ((IEnumerable)o).Cast<object>().Count();
确保o
类型具有实施IEnumerable
,并且您的文件顶部有using System.Linq
。
答案 2 :(得分:2)
它可以实现的最基本的界面是IEnumerable
。不幸的是,甚至来自LINQ的Enumerable.Count
都是为IEnumerable<T>
实现的,但您可以轻松编写自己的:{/ p>
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
}
值得注意的是,避免拳击确实是一种微观优化:它不太可能真正重要。但你可以一次,只需用这种方法,然后在任何地方利用它。