マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

ラムダ式っておじさん達にはユースケースがよく解りませんでしたが、

Java 8でもラムダ式がサポートされたようなので、私を含めて、

「そろそろ、ラムダ式をちゃんと覚えよう。」

という人向けのコンテンツを書いてみました。

ラムダ式

進化

おじさん達の知識で振り返って分析してみると、
中水準言語のC言語の関数ポインタから、

高水準言語の.NET言語(C#、VB)で、

と進化してきていることぐらいは解る(?)と思います。

これを見ると、

厳密には、以下のように進化してきています。

デリゲート(C# 1.0)

同じシグネチャを持つメソッドを格納するための変数を宣言し、それを利用できる。

デリゲート(C# 2.0)

デリゲートの代入時にインスタンス生成(new デリゲート名)を省略できる。

匿名メソッド(C# 2.0)

delegate構文を用いて「メソッド名を持たない処理」を記述できる。

  • イベント・ハンドラの例
    // Create a handler for a click event.
    button1.Click += delegate(System.Object o, System.EventArgs e)
                       { System.Windows.Forms.MessageBox.Show("Click!"); };
  • スレッド関数の例
    System.Threading.Thread t1 = new System.Threading.Thread
      (delegate()
        {
            System.Console.Write("Hello, ");
            System.Console.WriteLine("World!");
        });
    t1.Start();

定義済みデリゲート型(C# 3.0)

  • 定義済みデリゲート型(共通デリゲート型)(C# 3.0/.NET Framework 3.5)
  • ジェネリックの機能を用いて、3種類のデリゲートが定義され、
    「delegateキーワードを使ったデリゲート宣言」を省略できる。
  • 定義済みデリゲート
    ラムダ式で利用可能なメソッドを定義するために、
    最新の.NET 4.5ではActionとFuncの、T1-T16までのデリゲートが用意されている。

ラムダ式(C# 3.0)

定義済みデリゲート型とセットで使用する。

  • デリゲート型 / 式木(Expression Tree)を作成する作法
  • ラムダ演算子(=>) を用いて左辺にパラメタ、右辺に式やコードブロックを置く

用途

ラムダ式は、

  • LINQクエリ式や
  • デリゲートと多用する新しいAPIの

delegateを必要とするメソッドを
実行しやすくするために生まれてきたようです。

  • 参考
  • C#ラムダ式 基礎文法最速マスター - @IT
    http://www.atmarkit.co.jp/fdotnet/rapidmaster/rapidmaster_01/rapidmaster_01.html

    C#言語のラムダ式(lambda expressions)とは、
    デリゲート(delegate)や、メソッド・ベースのLINQ文の(例えば)
    WhereメソッドやSelectメソッドなどの引数をシンプルに記述するために、
    C# 3.0(=Visual C# 2008)以降で導入された言語仕様である。

これについては、以下の利用例を引き合いに出して説明したいと思います。

ポイント

文法

式形式

  • 引数がない場合
    () => {
      (式形式の実装)
    }
  • 引数が一つの場合
    (引数名) => {
      (式形式の実装)
    }
  • 引数が複数の場合
    (引数名1,引数名2,引数名3, ...) => {
      (式形式の実装)
    }

ステートメント形式

  • 引数がない場合
    () => (ステートメント形式の実装)
  • 引数が一つの場合
    引数名 => (ステートメント形式の実装);
  • 引数が複数の場合
    (引数名1,引数名2,引数名3, ...) => (ステートメント形式の実装)

仮引数と実引数

仮引数(parameter)

以下の場合、仮引数(parameter)を指定する。

  • デリゲートをメソッドの引数として渡す場合で、
  • 上記のデリゲートの引数をメソッドが内部から指定する場合

このため、一瞬どこから現れたのか不明な変数に見える。

LINQのメソッド ベースのクエリ構文などで使用される。

実引数(argument)

上記以外の場合は、実引数を指定する。

スコープ

ラムダ式では、そのスコープの外側にある
変数やメソッドを利用でき引数の肥大化が防げる。

(これは、匿名メソッドでも同じ)

利用例

ということで、引数をラムダ式にすることで、

delegateを必要とするメソッドを実行しやすくする。

ようなシーンが、ラムダ式の代表的な利用ケースではないか?と思います。

匿名メソッド代替

  • (プログラミング C# - 翔ソフトウェア (Sho's))
  • [C#][ラムダ式][匿名メソッド] ラムダ式は常に匿名メソッドよりシンプルに書ける?
    http://blog.shos.info/archives/2012/12/c_4.html

    しかし、ごく稀にだが、ラムダ式よりも匿名メソッドの方がシンプルになることがある。

  • ASP.NET MVC で WebGrid? を最大限に活用する - MSDN
    https://msdn.microsoft.com/ja-jp/magazine/hh288075.aspx

    新しい WebGrid?<T> 実装では、format パラメーターに
    Func<T, object> を受け取る新しい Column メソッドを追加しています。

    grid.Column(
      columnName: "EmailAddress", 
      header: "Email Address", 
      format: item => Html.EmailLink(
        (string)item.EmailAddress, 
        (string)item.EmailAddress, 
        ""
      ), 
      canSort: false
    )

LINQでの利用

  • LINQのメソッド ベースのクエリ構文で使用される(LINQプロバイダでは、ラムダ式を式として扱う)。
  • SELECTやWHEHE句などの動作のカスタマイズに一般的にはラムダ式を使用して記述する。
    var query5 = RowList
      .Where(p => p.Field<int>("年度") == 2012)
      .Select(p => new
      {
        年度 = p.Field<int>("年度"),
        種別 = p.Field<int>("種別"),
        生年度 = p.Field<int>("生年度"),
        平均人員2 = p.Field<int>("平均人員") / 12,
        支給年金額 = p.Field<int>("支給年金額")
      });

参考

Qiita

C# プログラミング ガイド

@IT

LINQ


Tags: :プログラミング, :.NET開発


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-04-27 (土) 00:46:11 (23d)