2011-02-14 123 views
2

有沒有辦法從函數中獲得收益回報數而不保留計數器變量?例如?收益率回報長度

IEnumerable<someobject> function 
    { 
     for loop 
      yield return something 

     int numberreturned = .... 
    } 

回答

10

這將打敗yield return目的。

使用yield return意味着你要實現發電機(MSDN調用的迭代器塊),即,計算每次返回對飛值的對象。根據定義,生成器可能是無限的,因此控制可能永遠不會離開您的for循環。

流以同樣的方式工作。要計算一個流的長度,你必須用盡它,你可能永遠不會從這樣做返回。畢竟,數據可能來自無限來源(例如/dev/zero)。

0

您可以使用擴展方法計數上了IEnumerable <>你的函數返回

function().Count() 
+2

這將對方法*返回*值起作用,但會強制評估*(可能永遠不會終止)。 – 2011-02-15 01:34:31

0

你可以使用IEnumerable.Count擴展方法!

我認爲yield return旨在讓編譯器隱式地使用它後面的語句構建一個基本的迭代器。

如果你想要一個更復雜的迭代器,那麼你可以用更明確的方式實現它。

+1

這將對方法*返回*值起作用 - 但會*強制評估*(可能永遠不會終止)。 – 2011-02-15 01:33:53

2

號這也不是沒有可能的反 - 沒有辦法從函數本身內訪問返回的流。 (如果可能的話,我想知道它會帶來什麼樣的奇怪的語義/怪癖?)

但是,即使問題不需要這樣的響應,這與計數器是完全可以的(如果可疑的話); - )請記住,當需要流(迭代器)中的下一項時調用閉包的這種構造形式是「魔術」 - 也就是說,根據需要,流量控制離開重新輸入yield return

IEnumerable<someobject> Function 
{ 
    int counter = 0; 
    foreach (...) { 
     counter++; 
     yield return ...; 
    } 
    // after here we know count -- /assuming/ control gets here 
    // 1) value can't be 'normally returned' 
    // 2) and if the stream evaluation never exhausts the loop above 
    // then flow-control will never get here 
} 

快樂編碼。