說說IEnumerable和yield

IEnumerable數據類型是我比較喜歡的數據類型,特別是其強類型IEnumerable<T>更得到Linq的支持使得代碼看起來更加優雅、整潔。spa

編寫返回值爲IEnumerable(或IEnumerabl<T>,下同)的方法時,會常常用到yield。近幾天在開發時碰到一個很頭疼的問題,終於在昨天解決。現將問題即解決過程記錄以下:對象

1、問題的出現:blog

編寫返回值爲IEnumerable的方法時,能夠用兩種方式返回值:接口

一、構造一個實現IEnumerable接口的對象,並返回。開發

二、在方法體內使用yield return逐個返回可能的值,若是中途遇到不須要再返回值的情形,可使用yield break;語句.原理

有一天突發奇想,能不能混合這兩種方式:若是業務邏輯不容許返回值,則用yield break,不然構建一個實現IEnumerable接口的對象返回呢?foreach

因而按以下思路編寫代碼:循環

寫完後發現return語句老是報錯:沒法從迭代器返回值。請使用yield return語句返回值,或使用yield break語句結束迭代。yield

2、問題的解決:數據類型

仔細思考後,發現迭代器的原理大體以下:

若是方法按迭代方法執行,則徹底以yield return語句來進行迭代。不然,返回一個IEnumerable對象,運行時會迭代該對象。

最終兩種方法重寫代碼均得到經過。

方式一:純迭代器方式

方式二:純構造IEnumerable對象

3、思考

一、從代碼的可讀性和優雅性兩個方面考慮,在容許的狀況下應儘量構造IEnumerable對象做爲返回值,確有必要才用yield return語句。

二、語句內出現foreach時,請儘可能借用強大的lamda表達式,而不是構造返回IEnumerable的方法或是使用foreach循環。

三、請儘可能使用IEnumerable<T>而不是IEnumerable,以便得到強大的linq支持。

下面的方法將根據方法名和參數列表從一個方法列表中找到最合適的方法:

而採用lamda表達式將獲得更優雅的表達:

寥寥兩行代碼,語義十分清晰,根本無須註釋.

相關文章
相關標籤/搜索