2008-09-22 41 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下的內容。有用的包裝,但不要避免在枚舉不支持重置的(罕見)情況下,您可能會遇到問題。

相關問題