Effective C# (Covers C# 6.0), (includes Content Update Program): 50 Specific Ways to Improve Your C#, 3rd Edition By Bill Wagner 讀後心得
本節延續 Item 31,一般對集合的操作大概分為兩個部分:
1. 回傳符合條件的元素。
2. 針對特定元素執行指定方法。
2. 針對特定元素執行指定方法。
利用 yield return 和委派的組合,可以達到以上要求。
首先,C# 語言提供了三種內建委派:
public delegate bool Predicate<in T>( T obj );
public delegate TResult Func<in T, out TResult>( T arg );
public delegate void Action<in T>( T obj );
接著利用幾個範例示範如何使用。
範例一:
public static IEnumerable<T> where<T>(
IEnumerable<T> sequence,
Predicate<T> filterFunc )
{
if ( sequence == null )
throw new ArgumentNullException( nameof( sequence ),
"Sequence must not be null" );
if ( filterFunc == null )
throw new ArgumentNullException( nameof( filterFunc ),
"Predicate must not be null" );
foreach ( T item in sequence )
{
if ( filterFunc( item ) )
yield return item;
}
}
利用輸入端定義的 Predicate<T>,迭代檢查集合內符合條件(回傳 true)的元素。
範例二:
public static IEnumerable<T> everyNthItem<T>(
IEnumerable<T> sequence, int period )
{
if ( sequence == null )
throw new ArgumentNullException( nameof( sequence ),
"Sequence must not be null" );
if ( period <= 0 )
throw new ArgumentNullException( nameof( period ),
"Period must be greater than zero" );
var count = 0;
foreach ( T item in sequence )
{
if ( ++count % period == 0 )
yield return item;
}
}
回傳符合 peirod 區間索引的元素。
範例三:
public static IEnumerable<T> select<T>(
IEnumerable<T> sequence, Func<T, T> method )
{
if ( sequence == null )
throw new ArgumentNullException( nameof( sequence ),
"Sequence must not be null" );
if ( method == null )
throw new ArgumentNullException( nameof( method ),
"Func must not be null" );
foreach ( T element in sequence )
yield return method( element );
}
迭代集合並回傳經過 Func<T,T> 方法修飾後的元素。
現實情況也不一定只會回傳T,有可能需回傳其他型別的元素。
利用泛型方法改寫程式:
public static IEnumerable<Tout> select<Tin,Tout>(
IEnumerable<Tin> sequence, Func<Tin, Tout> method )
{
if ( sequence == null )
throw new ArgumentNullException( nameof( sequence ),
"Sequence must not be null" );
if ( method == null )
throw new ArgumentNullException( nameof( method ),
"Func must not be null" );
foreach ( Tin element in sequence )
yield return method( element );
}
現在輸入集合元素型別為 Tin,回傳集合元素型別為 Tout。
結論:
1. 利用委派將集合迭代與元素操作兩者分離,依照不同輸入委派執行不同操作;集合重用性高。
1. 利用委派將集合迭代與元素操作兩者分離,依照不同輸入委派執行不同操作;集合重用性高。