2010年10月29日金曜日

今までよく分かってなかったラムダ式の使い道を考えてみた。

C#3.0から追加された言語仕様に「ラムダ式」というのがある。
どういうものかは、何となく知っていたが、今いちどういう局面で使うのか分からなかった。
(業務アプリでこういう実装がどうしても必要な局面もあんまり無いし)

昨日、『言語設計者たちが考えること』( http://amzn.to/azXdTs ) という本でC#の設計者であるアンダース・ヘルスバーグのインタビューを読んでいて、このあたりの認識に閃きを得た。

そこでラムダ式の使い道について、誰得なエントリーを書いてみる。
まぁ、僕個人の覚書なのでスルーしてもらってもOKです。

内容に関して、「お前そりゃ間違ってるよ」などのツッコミがあれば大歓迎です。
拙いコードですが、お暇な方はお付き合いください。

さて、まずはこんなコードを書いてみる。
static void Main(string[] args)
{
  TokyoOutput();
  OsakaOutput();            
}

private static void TokyoOutput()
{
   int result = 0;
   for (int i = 1; i <= 10; i++)
   {
      result += i;
   }
  Console.WriteLine("計算結果は" + result.ToString() + "ですね。" +
                                 Environment.NewLine);
}

private static void OsakaOutput()
{
    int result = 0;
    for (int i = 1; i <= 10; i++)
    {
        result += i;
    }
    Console.WriteLine("計算結果は" + result.ToString() + "やね。" + 
                                Environment.NewLine);
}
1から10を順に足しこんでいって、それを標準語で出力するメソッドと、大阪弁で出力するメソッド。ご覧の通り、異なるのは最後の結果出力のみで、計算処理は当然まったく同じロジック。 しかし、これはいくらなんでもブサイクすぎる。同じロジックが複数のメソッドに分散しているなんて。ってことで、ちょっと分離してみたらこうなった。
static void Main(string[] args)
{
    TokyoOutput(Calculate());
    OsakaOutput(Calculate());
}

private static int Calculate()
{
    int result = 0;
    for (int i = 1; i <= 10; i++)
    {
        result += i;
    }
    return result;
}

private static void TokyoOutput(int i)
{
   Console.WriteLine("計算結果は" + i.ToString() + "ですね。" + 
                                Environment.NewLine);
}

private static void OsakaOutput(int i)
{
    Console.WriteLine("計算結果は" + i.ToString() + "やね。" + 
                                Environment.NewLine);
}
うーん。なんか周りくどい…。 計算処理(Calculate)からの戻り値を次の出力メソッドに引数で渡すとか、面倒くさくね? ここにはコードを書かないけど、計算部分を抽象クラスにして、出力部分をoverrideするって手もある。しかしこの程度の処理でそこまで大げさにやるのもなんか嫌だ。 そこでラムダ式を使ってみる。
static void Main(string[] args)
{
    Action Tokyo = (int i) => 
                 Console.WriteLine("計算結果は" + i.ToString() +
                                   "ですね。" + Environment.NewLine);
    Action Osaka = (int i) => 
                 Console.WriteLine("計算結果は" + i.ToString() + 
                                   "やね。" + Environment.NewLine);
    Output(Tokyo);
    Output(Osaka);
}

private static void Output(Action outProc)
{
    int result = 0;
    for (int i = 1; i <= 10; i++)
    {
        result += i;
    }
    outProc(result);
}
うん。なんかすっきりした気がする。

ラムダ式を使う局面ってこんな感じでいいのかな?

要するに、関数をパラメータで渡すって事だから、メソッドの中の一部を外から見て任意にしたいって事だよね? うん。なんとなく分かってきた。もうちょっと掘り下げて考えていこうっと。

0 件のコメント:

コメントを投稿