パイプラインパターンに興味を持ったので、ちょこっとyieldの復習してました。
忘れてしまいそうなので、メモメモ。
パイプラインパターンに関しては、以下の記事を参考にしました。
イテレータをうまく利用する事がパイプラインの肝になりますね。
#region YieldSamples-01 public class YieldSamples01 : IExecutable { // // 最もベーシックな列挙可能クラス. // class SampleCollection1 { List_list; public SampleCollection1() { _list = new List { "Value1" ,"Value2" ,"Value3" }; } public IEnumerator GetEnumerator() { return _list.GetEnumerator(); } } // // Yieldを利用したパターン1 (IEnumerator を使用) // class SampleCollection2 { public IEnumerator GetEnumerator() { yield return "Value1"; yield return "Value2"; yield return "Value3"; } } // // Yieldを利用したパターン2 (IEnumerable を使用) // class SampleCollection3 { public IEnumerable InOrder { get { yield return "Value1"; yield return "Value2"; yield return "Value3"; } } } // // Yieldを利用したパターン3 (複数のIEnumerable を使用) // class SampleCollection4 { List _list; public SampleCollection4() { _list = new List { "Value1" ,"Value2" ,"Value3" }; } public IEnumerable InOrder { get { for(int i = 0; i < _list.Count; i++) { yield return _list[i]; } } } public IEnumerable ReverseOrder { get { for(int i = (_list.Count - 1); i >= 0; i--) { yield return _list[i]; } } } } // // yield breakを利用したパターン // class SampleCollection5 { public IEnumerable InOrderWithBreak { get { yield return "Value1"; yield return "Value2"; yield return "Value3"; yield break; // warning CS0162: 到達できないコードが検出されました。 //yield return "Value4"; } } } // // 簡易パイプライン用の各メソッド. // IEnumerable Range(int count, string prefix) { for(int i = 0; i < count; i++) { yield return string.Format("{0}-{1}", prefix, i); } } IEnumerable Upper(IEnumerable enumerables) { foreach(string val in enumerables) { yield return val.ToUpper(); } } IEnumerable AddCount(IEnumerable enumerables) { int count = 1; foreach(string val in enumerables) { yield return string.Format("{0}-{1}", val, count++); } } IEnumerable Filter(Predicate predicate, IEnumerable enumerables) { foreach(string val in enumerables) { if(predicate(val)) { yield return val; } } } // // 処理確認用実行メソッド // public void Execute() { SampleCollection1 col1 = new SampleCollection1(); foreach(string val in col1) { Console.WriteLine(val); } AddNewLine(); SampleCollection2 col2 = new SampleCollection2(); foreach(string val in col2) { Console.WriteLine(val); } AddNewLine(); SampleCollection3 col3 = new SampleCollection3(); foreach(string val in col3.InOrder) { Console.WriteLine(val); } AddNewLine(); SampleCollection4 col4 = new SampleCollection4(); foreach(string val in col4.InOrder) { Console.WriteLine(val); } foreach(string val in col4.ReverseOrder) { Console.WriteLine(val); } AddNewLine(); SampleCollection5 col5 = new SampleCollection5(); foreach(string val in col5.InOrderWithBreak) { Console.WriteLine(val); } AddNewLine(); foreach(string val in Filter(Judge, AddCount(Upper(Range(10, "value"))))) { Console.WriteLine(val); } } void AddNewLine() { Console.WriteLine(string.Empty); } bool Judge(string val) { string[] parts = val.Split('-'); if(parts.Length != 3) { return false; } int number = int.Parse(parts[2]); if((number % 2) == 0) { return true; } return false; } } #endregion