連載:[完全版]究極のC#プログラミング

Chapter6 ラムダ式(前編)

川俣 晶
2009/10/19

6.4 キャプチャされる変数

 上位スコープにアクセスできるというのは、実はいうほど簡単な話ではない。

 次のリスト6.5を見ていただきたい。常識的に考えれば、このプログラムは動作しないはずである。なぜなら、変数messageはCreateMethodメソッドからリターンした瞬間に消滅するが、ラムダ式が呼ばれるのはその後だからである。

using System;

delegate void MyAction();

class Program
{
  static MyAction CreateMethod()
  {
    string message = "Hello! World!";
    return ()=>
    {
      Console.WriteLine(message);
    };
  }

  static void Main(string[] args)
  {
    MyAction action = CreateMethod();
    action(); // 出力:Hello! World!
  }
}
リスト6.5 消滅した変数を参照した例

 しかし、このプログラムは正常に動作する。なぜかといえば、「外部変数のキャプチャ」という機能が用意されているからだ。

 外部変数のキャプチャとは、ラムダ式が上位スコープの変数を参照しているとき、その変数の寿命をラムダ式の寿命が尽きるまで延命する機能である(より正確にいえば、C#言語の仕様であり、仕様には「少なくとも、ラムダ式を参照するデリゲートがガベージコレクションできる状態になるまで延長されます」と記述されている)。

 この機能があるため、本来ならメソッドの実行が終わった時点で寿命が尽きたはずの変数messageは、ラムダ式から出力されるときにも生き延びていたのである。


 INDEX
  [完全版]究極のC#プログラミング
  Chapter6 ラムダ式(前編)
    1.6.1 おかずでもデザートでもなく“ご飯”
    2.6.2 ラムダ式とは何か?/【C#olumn】定義済みデリゲートを活用しよう
    3.6.3 ラムダ式は上位スコープにアクセスできる
  4.6.4 キャプチャされる変数
    5.6.5 注意を要するキャプチャの本質
    6.6.6 デリゲートの共変性と反変性
    7.6.7 デリゲートインスタンスの等価性
    8.6.8 ラムダ式で継承を置き換えてみる
    9.6.9 C# 2.0と匿名メソッド/【Exercise】練習問題
 
インデックス・ページヘ  「[完全版]究極のC#プログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間