2008-09-22 80 views
9

我试图找到最可重用,但优雅的代码段可能确定是否IEnumerable。理想情况下,这应该是我可以随时调用的一个函数,我需要告诉IEnumerable是否为空。在.NET中,什么是确定IEnumerable是否为空的可靠,优雅,可重用的代码片段?

虽然我已经开发了一个对.NET 3.5的答案,迄今为止我的工作很好,但我目前的想法是,没有完美的答案,因为IEnumerable可以在技术上封装一个集合(或迭代器队列)它迭代时的基础结果,这会导致问题。但是,这也会阻碍实现IEnumerable.Count(),这并不能阻止MS提供它。

所以我想我会把它放在这里看看是否有人有更好的,并在其他人应该找到它有用。

编辑:哇,我不能相信我不知道IEnumerable.Any。我知道它存在,但从不费心检查它做了什么。让这是一个教训。阅读文档。只是因为一个方法名并不意味着它做你想做的事,并不意味着它没有做你想做的事。

回答

22
!enumerable.Any() 

将尝试仅抓住第一个元素。

要扩展这种工作方式/原因,any可确定IEnumerable的任何组件是否与给定函数匹配,如果没有给定函数,则任何组件都会成功,意味着如果元素存在于可枚举。

+0

哇....真不敢相信,我不知道这件事。谢谢! – 2008-09-22 20:24:37

+2

这是新的.NET 3.5 – Keith 2008-09-22 20:41:02

2

对于.NET 1/2:

IEnumerator e; 
try 
{ 
    e = enumerable.GetEnumerator(); 
    return e.MoveNext(); 
} 
finally 
{ 
    if (e is IDisposable) 
     e.Dispose(); 
} 

或者使用泛型:

using (IEnumerator<T> e = enumerable.GetEnumerator()) 
{ 
    return e.MoveNext(); 
} 
0

有一件事要小心有以下两种方法之一是,并非所有的枚举可上卷例如,所有的System.Data.IDataReader实现只能运行一次。

在这些情况下,只要您考虑到它可能不会循环一次,您在foreach循环中确实没有成本。

2

你是对的,没有完美的答案。 IEnumerable只支持迭代,并不保证枚举是可重复的。您不能确定一个枚举是否包含元素而不调用MoveNext至少一次,并且一旦您完成了这些操作,您将无法保证能够重用该枚举:IEnumerable.Reset允许引发NotSupportedException。从http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.reset.aspx

“Reset方法提供了COM互操作性,它不一定需要实现;相反,实现者可以简单地引发NotSupportedException。

扩展方法,如IEnumerable <T> .Count和IEnumerable <T>。任何需要调用MoveNext下的内容。有用的包装,但不要避免在枚举不支持重置的(罕见)情况下,您可能会遇到问题。

相关问题