匿名メソッド (C# プログラミング ガイド)Anonymous Methods (C# Programming Guide)

C# 2.0 より前のバージョンでは、デリゲートを宣言するには名前付きメソッドを使用するしかありませんでした。In versions of C# before 2.0, the only way to declare a delegate was to use named methods. C# 2.0 では匿名メソッドが導入され、C# 3.0 以降では、インライン コードを記述するための本来の方法として、匿名メソッドに代わってラムダ式が使用されるようになりました。C# 2.0 introduced anonymous methods and in C# 3.0 and later, lambda expressions supersede anonymous methods as the preferred way to write inline code. ただし、このトピックに記載した匿名メソッドに関する情報は、ラムダ式にも適用されます。However, the information about anonymous methods in this topic also applies to lambda expressions. ラムダ式にはない機能を匿名メソッドが備えているケースが 1 つあります。There is one case in which an anonymous method provides functionality not found in lambda expressions. 匿名メソッドではパラメーター リストを省略できます。Anonymous methods enable you to omit the parameter list. つまり、匿名メソッドを、さまざまなシグネチャを持つデリゲートに変換できます。This means that an anonymous method can be converted to delegates with a variety of signatures. これはラムダ式では不可能です。This is not possible with lambda expressions. ラムダ式の詳細については、「ラムダ式」を参照してください。For more information specifically about lambda expressions, see Lambda Expressions.

匿名メソッドは、基本的にコード ブロックをデリゲート パラメーターとして渡すときに作成します。Creating anonymous methods is essentially a way to pass a code block as a delegate parameter. 2 つの例を挙げます。Here are two examples:

// Create a handler for a click event.
button1.Click += delegate(System.Object o, System.EventArgs e)
                   { System.Windows.Forms.MessageBox.Show("Click!"); };
// Create a delegate.
delegate void Del(int x);

// Instantiate the delegate using an anonymous method.
Del d = delegate(int k) { /* ... */ };

匿名メソッドを使用すると、別のメソッドを作成する必要がないため、デリゲートをインスタンス化する際のコーディングのオーバーヘッドを削減できます。By using anonymous methods, you reduce the coding overhead in instantiating delegates because you do not have to create a separate method.

たとえば、デリゲートの代わりにコード ブロックを指定すると、メソッドを作成するのが余分なオーバーヘッドと思われる場合に役立つことがあります。For example, specifying a code block instead of a delegate can be useful in a situation when having to create a method might seem an unnecessary overhead. 新しいスレッドを開始する場合などがそのよい例です。A good example would be when you start a new thread. このクラスではスレッドを作成し、スレッドが実行するコードも含みますが、デリゲート用の追加のメソッドは作成していません。This class creates a thread and also contains the code that the thread executes without creating an additional method for the delegate.

void StartThread()
{
    System.Threading.Thread t1 = new System.Threading.Thread
      (delegate()
            {
                System.Console.Write("Hello, ");
                System.Console.WriteLine("World!");
            });
    t1.Start();
}

コメントRemarks

匿名メソッドのパラメーターのスコープは、"匿名メソッド ブロック" です。The scope of the parameters of an anonymous method is the anonymous-method-block.

匿名メソッド ブロックの内部で使用しているジャンプ ステートメント (gotobreakcontinue など) のジャンプ先がブロックの外部にある場合はエラーになります。It is an error to have a jump statement, such as goto, break, or continue, inside the anonymous method block if the target is outside the block. また、匿名メソッド ブロックの外部で使用しているジャンプ ステートメント (gotobreakcontinue など) のジャンプ先がブロックの内部にある場合もエラーになります。It is also an error to have a jump statement, such as goto, break, or continue, outside the anonymous method block if the target is inside the block.

匿名メソッドの宣言をスコープに含むローカル変数とパラメーターは、匿名メソッドの "外部" 変数と呼ばれます。The local variables and parameters whose scope contains an anonymous method declaration are called outer variables of the anonymous method. たとえば、次のコード セグメントに示されている n は外部変数です。For example, in the following code segment, n is an outer variable:

int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };

外部変数 n への参照は、デリゲートの作成時に "キャプチャ" されるといわれます。A reference to the outer variable n is said to be captured when the delegate is created. ローカル変数とは異なり、匿名メソッドを参照するデリゲートがガベージ コレクションの対象になるまで、キャプチャされた変数の有効期間を拡張します。Unlike local variables, the lifetime of a captured variable extends until the delegates that reference the anonymous methods are eligible for garbage collection.

匿名メソッドは、外部スコープの ref パラメーターや out パラメーターにアクセスできません。An anonymous method cannot access the ref or out parameters of an outer scope.

"匿名メソッド ブロック" 内のアンセーフ コードにはアクセスできません。No unsafe code can be accessed within the anonymous-method-block.

匿名メソッドは、is 演算子の左辺では使用できません。Anonymous methods are not allowed on the left side of the is operator.

Example

次の例は、デリゲートをインスタンス化する 2 つの方法を示しています。The following example demonstrates two ways of instantiating a delegate:

  • デリゲートと匿名メソッドを関連付ける。Associating the delegate with an anonymous method.

  • デリゲートと名前付きメソッド (DoWork) を関連付ける。Associating the delegate with a named method (DoWork).

どちらの場合も、デリゲートを呼び出すと、メッセージが表示されます。In each case, a message is displayed when the delegate is invoked.

// Declare a delegate.
delegate void Printer(string s);

class TestClass
{
    static void Main()
    {
        // Instantiate the delegate type using an anonymous method.
        Printer p = delegate(string j)
        {
            System.Console.WriteLine(j);
        };

        // Results from the anonymous delegate call.
        p("The delegate using the anonymous method is called.");

        // The delegate instantiation using a named method "DoWork".
        p = new Printer(TestClass.DoWork);

        // Results from the old style delegate call.
        p("The delegate using the named method is called.");
    }

    // The method associated with the named delegate.
    static void DoWork(string k)
    {
        System.Console.WriteLine(k);
    }
}
/* Output:
    The delegate using the anonymous method is called.
    The delegate using the named method is called.
*/

関連項目See Also

C# リファレンスC# Reference
C# プログラミング ガイドC# Programming Guide
デリゲートDelegates
ラムダ式Lambda Expressions
アンセーフ コードとポインターUnsafe Code and Pointers
メソッドMethods
名前付きメソッドを使用したデリゲートと匿名メソッドを使用したデリゲートDelegates with Named vs. Anonymous Methods