読者です 読者をやめる 読者になる 読者になる

【C#】C#でboost::bindを実装してみた(3)

前回の続きです
引数の部分束縛を実装に以下問題がありました

①どの引数を束縛するのかはどうやって指定するの?
②たとえ引数を適当を渡しても、両方も当てはまるのでエラーが発生します

これらを対策してみました

①束縛する引数を指定する

Placeholder

引数を束縛を指定するため、Placeholderを追加してみた

public static class Boost
{
    public class Placeholder{}
    public static Placeholder _X = new Placeholder();
}

②両方も当てはまる

修正前
// Action(P1,P2) -> Action(P1)
public static Action<P1> Bind<P1,P2>(Action<P1,P2> action,P1 p1,P2 p2)
{ return (a1) => action(a1,p2); }
// Action(P1,P2) -> Action(P2)
public static Action<P2> Bind<P1,P2>(Action<P1,P2> action,P1 p1,P2 p2)
{ return (a2) => action(p1,a2); }
修正後
// Action(P1,P2) -> Action(P1)
public static Action<P1> Bind<P1,P2>(Action<P1,P2> action,Placeholder p1,P2 p2)
{ return (a1) => action(a1,p2); }
// Action(P1,P2) -> Action(P2)
public static Action<P2> Bind<P1,P2>(Action<P1,P2> action,P1 p1,Placeholder p2)
{ return (a2) => action(p1,a2); }

束縛したい引数をPlaceholderにする
ポリモーフィズムを利用します

検証

static public void DelegateMethod(int a , int b)
{
    Console.WriteLine(a.ToString() +":" + b.ToString() );
}
Action<int> action = null;
action += Boost.Bind<int,int>(DelegateMethod,10,Boost._X);
action += Boost.Bind<int,int>(DelegateMethod,Boost._X,10);
action(20);
10:20
20:10

やりたいことは問題なくできました、が

Action<int> action = Boost.Bind<int,int>(DelegateMethod,Boost._1,Boost._1);
action(10); // 出力は 10:10
Action<int> action = Boost.Bind<int,int>(DelegateMethod,Boost._2,Boost._1);
action(10,20); // 出力は 20:10

みたいなことはできませんでした
もっと勉強して、いつか再挑戦してみます

以上、「C#でboost::bindを実装してみた 」でした

おまけ:サンプル

パラメータ0個から2個までの実装です
やはり全パターン対応は大変ですね