C#のデリゲート

C#において関数をオブジェクトみたいに扱う方法がデリゲートだと認識した。

まず簡単な例

int Vai(int x)
{
  return x * 2;
}

delegate int DelegateTest(int x);
DelegateTest test = new DelegateTest(Vai);

Console.WriteLine(test(7));
//OUTPUT::14

という風にやる(実際は初期化はグローバルフィールドではできない仕様になってるので適当な関数の中でやることになるが)

Action,Funcとは

Actionとは引数、帰り値なしのデリゲートを簡単に書く仕組みみたい。

void Scream()
{
  Console.WriteLine("uoooooooooo");
}
//上のメソッドに対して、
delegate void Hoge();
Hoge hoge = new Hoge(Scream);
hoge();

とやるのと

Action hoge = Scream;
hoge();

とやるのは同じことになる。確かに引数返り値なしの関数をActionと呼ぶのはなかなか直観的な感じもする。
引数が一つ、返り値がなしでも同じようにActionは使えるみたい。
Funcもほとんど同じ。こっちは引数、返り値がともに一つの場合に使う。
上のVaiの例を使うと、

Func<int,int> hoge = Vai;
Console.WriteLine(hoge(8));
//OUTPUT::16

とも書ける。

よく匿名関数とセットで語られるのは、わざわざデリゲートに食わせるためにちゃんとした関数定義を書くのが馬鹿らしいと思うからだと思う。たとえば上のVai関数がそうだが、どうせ出番ないんだしわざわざVaiとかいう名前を考えるのもだるい。そういう時に匿名関数もしくはラムダ式を使う。
例はラムダ式のみ。

Func<int,int> hoge = (int x) => x * 2;

最初の例からするとだいぶシンプルになった。

まとめ

デリゲートは関数をオブジェクト化する仕組み
Action,Funcはシンタックスシュガーみたいなもん。

具体的な使い道としてはパッと思いつかない。JSの関数を感覚が近い感じだしそれっぽく使ったりするのだろうか。
それにしたって違う言語がある概念の取得に役に立つのはなんだか楽しいな。物事をちがう方面から見れている感じだ。