在.NET中,确定IEnumerable是否为空的什么是可靠,可重用的可靠代码?

StackOverflow https://stackoverflow.com/questions/117355

  •  02-07-2019
  •  | 
  •  

我正在尝试找到最可重用但优雅的代码片段,以确定是否为IEnumerable。在理想情况下,这应该是一个函数,我可以在任何时候告诉我IEnumerable是否为空。

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

所以我想我会把它放到SO上看看是否有人有更好的,以防万一其他人觉得它有用。

编辑:哇,我无法相信我不知道IEnumerable.Any。我知道它存在,但从来没有费心去检查它做了什么。让这成为一个教训。阅读文档。仅仅因为方法名称并不意味着它能够达到你想要的效果,并不意味着它不能达到你想要的效果。

有帮助吗?

解决方案

!enumerable.Any()

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

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

其他提示

对于.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();
}

你说得对,没有完美的答案。 IEnumerable仅支持迭代,并不保证枚举是可重复的。您无法确定枚举是否包含元素而不调用MoveNext至少一次,并且一旦完成,您无法保证能够重用枚举:IEnumerable.Reset允许抛出NotSupportedException。来自 http://msdn.microsoft.com/en -us /库/ system.collections.ienumerator.reset.aspx

<!> quot;为COM互操作性提供了Reset方法。它不一定需要实施;相反,实现者可以简单地抛出NotSupportedException。<!> quot;

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

使用这些方法中的任何一个都要注意的是,并非所有枚举都可以回滚,例如System.Data.IDataReader的所有实现只能运行一次。

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

第一种方法有一个简单的Empty扩展方法实现: http://signum.codeplex.com/SourceControl/changeset/view/25903# 510468个

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top