2012-09-24 71 views
3

我發現在open source project下面的方法:爲什麼在這裏使用yield return?

static IEnumerable<T> Cat<T>(T t) { 
     yield return t; 
    } 

據我的理解,它不是別的,只是返回一個包含IEnumerable<T>t。如果我是對的,它就等於return new List<T>{t};,這裏使用yield return的目的/優勢是什麼?如果我錯了,我錯過了什麼?

Full source can be found here

+0

它是如何使用的? – Oded

+0

這兩者彼此接近,但IEnumerable 與列表不同,所選的方法是我可以想到的最簡單的方式來獲取其中的單個項目的集合。 – 48klocs

回答

5

這只是一個包含單個元素的可枚舉類型(t)。實際上,你是正確的 - 它實際上將非常相似,只是用一個元素或具有一個元素的新陣列等返回新的List<T>

主要區別在於返回的類型不會實際上是一個List<T>或一個數組 - 它將是一個編譯器生成的類型。例如,您將無法將結果轉換爲列表並添加元素。在實際應用中,它會像您所描述的那樣返回新的List<T>

除開發人員可能更喜歡這種語法外,可能沒有真正的優勢。我懷疑是可能被用來允許單個元素與API的其他部分一起工作,期望IEnumerable<T>被傳入,儘管方法名稱有一點需要,IMO。

+0

+1在考慮這樣的事情時,無法將其重新轉換爲「列表」可能是一個重要因素,同意(儘管當然不是這種情況)。 – Bartosz

0

此功能的單個項目轉換爲枚舉 如果你有一個枚舉,並要附加一個項目,例如:

IEnumerable<someType> Columns; 

var headers = String.Join(",", Columns.Select(c => c.Name).Concat(new string[] { "Last Column" })); 

它是更好的寫

var headers = String.Join(",", Columns.Select(c => c.Name).Concat(Cat("Last Column"))); 
3

返回實際收集和使用yield之間的區別僅僅是您返回的對象的類型。

如果您返回實現IEnumerable<T>的任何集合,則返回的對象的實際類型將爲該類型。例如,如果您返回List<T>,則返回的引用將是IEnumerable<T>類型,但引用指向的對象的實際類型是List<T>的實例。

如果使用yield,則編譯器將創建一個沒有已知名稱的枚舉器對象。返回的引用的類型也將是IEnumerable<T>,但引用指向的對象的實際類型將是編譯器創建的內容。

例如得到一個枚舉的一個整數創建的類型名稱:

Console.WriteLine(Cat<int>(42).GetType().Name); 

將顯示內部名稱,編譯器使用,例如這樣的結果,我從代碼有:

<Cat>d__5`1 

如果該函數將返回一個List<int>代替,類型將顯示爲:

List`1 

爲讓編譯器創建此枚舉的動機可能只是它比這樣的短:

static IEnumerable<T> Cat<T>(T t) { 
    List<T> list = new List<T>(1); 
    list.Add(t); 
    return list; 
} 

(你可以把它寫使用快捷鍵有點短於C#的新版本,但仍沒有短到yield

當類型是一個集合,你可以施放參考實際類型和集合中更改值:

IEnumerable<int> ienum = Cat<int>(42); 

((List<int>)ienum)[0] = 1337; 

foreach (int value in ienum) { 
    Console.WriteLine(value); 
} 

將輸出:

1337 
相關問題