2009-07-01 60 views
21

退貨類型爲IGrouping<TKey, TElement>IDictionary<TKey, TValue>時,我可以使用yield return嗎?收益回報僅適用於IEnumerable <T>?

+0

可能的重複[一些幫助理解「yield」](http://stackoverflow.com/questions/317462/some-help-understanding-yield) – nawfal 2014-07-09 06:54:38

回答

36

yield return作品正好是4的情況:

  • IEnumerable
  • IEnumerable<T>
  • IEnumerator
  • IEnumerator<T>

這是因爲它在內部建立一個狀態機;字典(等)將不可能與此。你當然可以只用return來代替。

+0

如果您想自己實現IEnumerable,請點擊http://csharpindepth.com/articles/chapter6/iteratorblockimplementation.aspx。 – Rory 2012-09-16 23:01:44

+0

@Rory是的,自己實現它是一個龐大的PITA,我現在無法想象任何「正常」的原因,現在迭代器塊存在。我有一些這樣的,但通常是爲了兼容需要在C#1.2編譯器上構建的項目;不完全是「正常」的情況。 – 2012-09-17 06:48:13

0

nope,只是ienumerable :-)

+0

不正確;請參閱我的答案; -p – 2009-07-01 19:53:01

1

我不這麼認爲。雖然documentation沒有完全拼出來,但其措辭方式意味着只有在方法的返回類型爲IEnumerableIEnumerable<T>時才能使用它。您可能可以編寫一個實現IGrouping的類,並給出IEnumerable(這將從您的方法使用yield return返回),但這是真正唯一的選擇。

+1

語言規範將其拼寫出來,請參閱ECMA 334中的8.18 – 2009-07-01 19:54:22

2

不,因爲迭代器塊只是一個由編譯器代表您構建的狀態機。該功能可讓您「屈服」並將項目作爲序列的一部分。

如果返回類型不是IEnumerable<T>(例如IDictionary),編譯器將不得不生成實現該接口的方法,在這一點上它沒有多大意義,因爲您將使用集合而不是一個序列。

15

然而,您可以返回IEnumerable<KeyValuePair<K,V>>,這將類似於字典。然後你會返回KeyValuePairs。你甚至可以用另一種方法來包裝這個方法,從返回中創建一個字典。第一種方法唯一不能保證的是按鍵的唯一性。

+7

然後,您將失去O(1)訪問時間,並且必須遍歷每個單個KVP才能找到正確的密鑰,最差的O(n)次。 – 2009-08-18 19:30:15

4

答:編號A yield return語句可用於只有在返回類型爲IEnumeratorIEnumerator<T>IEnumerable,或IEnumerable<T>

從§8.14的C# 3.0 spec

yield語句是在迭代器塊使用的(第8.2節),以產生一個值枚舉器對象(§10.14.4)或枚舉對象(§10.14.5 )的迭代器或者表示迭代的結束。

從§10.14.4:

枚舉器對象具有以下特點:

  1. 它實現IEnumeratorIEnumerator<T>,其中T是迭代器的產率類型。

[...]

從§10.14.5:

可枚舉對象具有以下特點:

  1. 它實現IEnumerableIEnumerable<T>,其中T是迭代器的產率類型。

[...]

2

只需調用iterator方法和鏈ToDictionaryGroupBy後,和你有類似的事情。如果你需要從幾個地方調用它,請將它放在單行包裝器方法中。

-2

由於yield return可以使用類型爲IEnumerator<T>爲什麼不做這樣的事情呢?

internal static IEnumerable<Dictionary<byte, string>> GetData() 
    { 
     Dictionary<byte, string> result = GetMyData(); //read from db 
     yield return result; 
    } 

希望它有幫助。