Effective C# (Covers C# 6.0), (includes Content Update Program): 50 Specific Ways to Improve Your C#, 3rd Edition By Bill Wagner 讀後心得
本節將介紹利用 yield return 語法,創建可組合的集合查詢。配合 IEnumerable<T> 回傳值,讓查詢結果得以重用,以及減少儲存空間消耗。
1. 利用 yield return 語法取得可重用的集合。
範例程式碼:
public static void unique( IEnumerable<int> nums )
{
var uniqueValues = new HashSet<int>( );
foreach ( var num in nums )
{
if ( !uniqueValues.Contains( num ) )
{
uniqueValues.Add( num );
Debug.WriteLine( num.ToString( ) );
}
}
}
此範例雖然可以正常執行,但是無法重用。若想對回傳集合做不同操作,需另外撰寫方法。然而利用 yield return 特性可以做到。
利用 yield return 語法改寫:
public static IEnumerable<int> uniqueV2( IEnumerable<int> nums )
{
var uniqueValues = new HashSet<int>( );
foreach ( var num in nums )
{
uniqueValues.Add( num );
yield return num;
}
}
用戶端程式碼:
foreach ( var num in uniqueV2( array ) )
Debug.WriteLine( num.ToString( ) );
uniqueV2 現在回傳的型別為 IEnumerable<int>,用戶端可以自行決定其對內部元素操作。增加了重用性。
進一步改寫成泛型版本,讓方法更加一般化。
public static IEnumerable<T> uniqueV3<T>( IEnumerable<T> sequence )
{
var uniqueValues = new HashSet<T>( );
foreach ( var item in sequence )
{
uniqueValues.Add( item );
yield return item;
}
}
2. 利用 yield return 創建可組合的集合查詢。
範例:
增加一個篩選條件。
public static IEnumerable<int> square( IEnumerable<int> nums )
{
foreach ( var num in nums )
yield return num * num;
}
將其和 uniqueV2 組合。
用戶端程式碼:
foreach ( var num in square( uniqueV2( array ) ) )
Debug.WriteLine( num.ToString( ) );
Note:由於 yield return 特性為需要取得值時才執行,延後執行確保取得當前最新的值;而在查詢期間也不會產生額外的集合副本(直接回傳原始集合內被查詢的元素副本),減少記憶體消耗。
3. 合併不同集合並回傳合併後的結果。
public static IEnumerable<string> zip( IEnumerable<string> first,
IEnumerable<string> second )
{
using ( var firstSequence = first.GetEnumerator( ) )
{
using ( var secondSequence = second.GetEnumerator( ) )
{
while ( firstSequence.MoveNext( ) && secondSequence.MoveNext( ) )
yield return $"{firstSequence.Current}, {secondSequence.Current}";
}
}
}
結論:
1. 利用 yield return 回傳可重用的集合查詢結果。
2. 利用 yield return 組合不同查詢方式。
3. 利用 yield return 減少記憶體空間消耗。
1. 利用 yield return 回傳可重用的集合查詢結果。
2. 利用 yield return 組合不同查詢方式。
3. 利用 yield return 減少記憶體空間消耗。