#blog2navi() *C#:サロゲートペアを考慮した文字の列挙に拡張メソッドも使えるようにする [#x7a735e4] LEFT:Prev: [[[C#:サロゲートペアを考慮した文字の列挙に foreach を使えるようにする>ぼやきごと/2013-03-14/C#:サロゲートペアを考慮した文字の列挙に foreach を使えるようにする]]] [[昨日の記事>ぼやきごと/2013-03-14/C#:サロゲートペアを考慮した文字の列挙に foreach を使えるようにする]]の続き…というか改良版。 前回作った @code{TextElementEnumerable}; クラスは @code{IEnumerable}; インタフェースを実装していましたが、 @code{System.Linq.Enumerable}; 静的クラスにある豊富な拡張メソッドを利用するためには @code{IEnumerable<T>}; ジェネリックインタフェースをこそ実装すべきです。~ そして @code{IEnumerable<T>.GetEnumerator}; メソッドの実装には @code{yield return}; 文を使うのが簡単です。 というわけで、改良した @code{TextElementEnumerable}; クラスはこちら。 #code(csharp){{ using System; using System.Collections; using System.Collections.Generic; using System.Globalization; namespace ruche.util { /// <summary> /// 文字列に対するUnicode文字の列挙子を公開するクラス。 /// </summary> public class TextElementEnumerable : IEnumerable<string> { /// <summary> /// コンストラクタ。 /// </summary> /// <param name="source">列挙対象となる文字列。</param> public TextElementEnumerable(string source) { this.Source = source; } /// <summary> /// 列挙対象文字列を取得する。 /// </summary> public string Source { get; private set; } /// <summary> /// Unicode文字の列挙子を取得する。 /// </summary> /// <returns>Unicode文字の列挙子。</returns> public IEnumerator<string> GetEnumerator() { var e = StringInfo.GetTextElementEnumerator(this.Source); while (e.MoveNext()) { yield return e.GetTextElement(); } } #region IEnumerable の明示的実装 IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } #endregion } } }} これで @code{System.Linq.Enumerable}; 静的クラスの拡張メソッドも利用可能になります。 #code(csharp){{ string text = "あいうえお"; // 拡張メソッドが使える(using System.Linq が必要) int unicodeLen = (new TextElementEnumerable(text)).Count(); // foreach でも型推論が使える foreach (var s in new TextElementEnumerable(text)) { // 内容略 } }} ちなみに、利用する場所が限られているのならば、わざわざ @code{TextElementEnumerable}; クラスを作らずとも下記のようなメソッドを作るだけでも事足ります。 #code(csharp){{ /// <summary> /// 文字列に対するUnicode文字の列挙子を公開するオブジェクトを取得する。 /// </summary> /// <param name="source">列挙対象となる文字列。</param> /// <returns>Unicode文字の列挙子を公開するオブジェクト。</returns> private IEnumerable<string> GetTextElementEnumerable(string source) { var e = StringInfo.GetTextElementEnumerator(source); while (e.MoveNext()) { yield return e.GetTextElement(); } } }} これで @code{new TextElementEnumerable(xxx)}; の代わりに @code{GetTextElementEnumerable(xxx)}; と書くことができます。 RIGHT:Category: [[[プログラミング>ぼやきごと/カテゴリ/プログラミング]]][[[C#>ぼやきごと/カテゴリ/C#]]] - 2013-03-15 00:05:35 ---- RIGHT:&blog2trackback(); #comment(above) #blog2navi()