【C#】デリゲートとは | 関数・メソッドをカプセル化する機能

C#の目玉機能として「LINQ」と呼ばれるものがありますが、そのLINQの歴史をさかのぼっていくと、最も根本にあるのが「デリゲート」と呼ばれる技術になります。

ラムダ式をしっかりと理解するためには、最初の一歩である「デリゲート」を学ぶことが重要です。現在ではラムダ式の普及により使用頻度が少なくなったデリゲートですが、これについて学んでおくことは非常に重要です。

デリゲートとは

まずは「デリゲート」とは何か、という部分から解説していきます。「デリゲート(delegate)」とは英語で「委任する、委譲する、委託する、委嘱する」といった意味を持つ単語です。プログラミング的な意味でのデリゲートは「メソッドを参照を可能とする型」という感じです。

厳密には「処理をカプセル化する」という表現方法が正しいのですが、要するに「データでなく処理を持っている型」と考えておくとスッキリするかなと思います。デリゲートの「委任・委譲」という考え方は、処理を「委任」するという意味合いで、「他で記述された処理に実際の挙動を任せる」という意味になります。

デリゲートを使用する方法

「デリゲート」を使用してC#のプログラミングを記述するには「デリゲート型」と呼ばれる変数を使用しなくてはなりません。デリゲートが型の変数を宣言することで、「処理の中身を入れる箱」を作成でき、その中に処理を格納することが可能となります。

delegate型の変数

実際の処理部分は箱の中身として記述された(渡された部分)を使用して処理をします。デリゲートは「箱」を定義することであり、その処理の中身は別の部分で記述できると覚えておきましょう。デリゲート型の変数は以下のようにして定義できます。

delegate 戻り値の型 デリゲート型名(引数リスト);

実際では以下のようにデリゲート型の変数を記述します。実際のソースコードでは以下のような形式でデリゲートを記述します。

delegate void WriteConsole(string str);

上記のようなデリゲート変数の場合、string型の引数を1つ取り、何も戻さない(void型)メソッドと紐づけて使用できます。delegateキーワードを使うことにより「カプセル化された処理を使用します」という宣言になるのです。それ以外は通常のメソッドの定義と同様の記述になります。

なぜデリゲートが重要なのか

それでは、「デリゲート」がどうして重要になるのかを解説していきます。「デリゲート」の重要な部分は「処理をカプセル化できる」という部分に集約されます。

処理をカプセル化することで変数のように扱うことができ、必要な時に実行できるという柔軟性を持つようになるからです。その考え方としてデリゲート型の宣言が必要になります。

これが処理を入れる「箱」だけ作っておいて、必要な時に必要な処理を詰めることができます。

デリゲート型の変数にするだけで「メソッドが変数のように扱える」という部分がミソなのです。この考え方により処理を可変的に代入できるだけでなく、処理を必要な時まで持ちまわることができるようになりました。

この考え方がLINQなどに脈々と受け継がれていくことになります。またそこから発展して、メソッドの引数としてデリゲートを「外側から引き渡せる」ようになっていきます。メソッド内で実行したい処理を、外側から引数で渡せることにより、処理の書き方に柔軟性を与えられます。