No more Death March

あるSEのチラシの裏 C# WPF

インターフェースを考える(13)コレクションとインターフェース

IActionやISpecificationなど、単一の要素に対するインターフェースでしたが、
実際にアプリケーションを組むとなると必ずコレクションに対する操作が必要になると思います。

今回は拡張メソッドを使って、都度コーディングをしなくてもこれらインターフェースの処理を使い回す方法を考えます。

まずIActionについて、以下のような拡張メソッドを用意しました。

        public static void DoEach<T>(this IEnumerable<T> actors,IAction<T> action)
        {
            new List<T>(actors).ForEach(x => x.Do(action));
        }

        public static IEnumerable<T> DoEachFluent<T>(this IEnumerable<T> actors, IAction<T> action)
        {
            actors.DoEach(action);
            return new List<T>(actors);
        }

やっていることは単純でListクラスのForEachメソッドにIActionを実行する匿名メソッドを指定しているだけです。

同じようにISpecificationを使った拡張メソッドをIEnumerableに追加します。

using System.Collections.Generic;

namespace Nmdm.Specifications
{
    public static class ISpecificationExtension
    {
        public static IEnumerable<T> FindAll<T>(this IEnumerable<T> collection,ISpecification<T> spec)
        {
            return new List<T>(collection).FindAll(x => spec.IsSatisfiedBy(x));
        }
    }
}

こちらも同じ要領でListのFindAllメソッドにboolを返す匿名メソッドを指定しているだけ。

どちらもやっていることはデリゲートを使うメソッドをインターフェースに適用させてるだけですね。

C#実践開発手法でもコードに適用力を持たせるならデリゲートよりクラスですよと書いてあるけど、
それなら標準のデリゲートと同じようにインターフェースも用意してあれば良かったのになぁ・・・