C# Advent Calendar 2018 - Qiita 3日目の記事です
題名は私のことです。
C#を業務レベルで使い始めて 1か月
業務のコードで => (アロー) (イカちゃんマーク) に出くわしました。
delegate という言葉に出くわして詰まりました。
率直に沸いた疑問
- delegate ってなにそれ おいしいの?
- => が イカにしか見えない
- Action action = () => Console.WriteLine("Hello, World!!"); イコールが()に挟まって イカが発生していて更に謎
- Func< T >Action< T > 関数に "< > " がついていて謎
つまり delegate こそが本質 (多分)
ざっくり調べたところでは LINQの前にラムダ式 ラムダ式のはるか前に
delegate を理解しないといけないっぽいことがわかりました。
初学者は公式をみてもわからない delegate ってなにそれおいしいの?
デリゲート (C# プログラミング ガイド) | Microsoft Docs
・・・・
わからないということが分かった
もそもなぜ delegate が出てくるのか
”デリゲートは日本語では「委譲」と訳されることが多い。委譲という言葉が分かりにくいと思うなら、代表者と考えてもよい。何かの処理を実行させたいときに、処理機能を持つメソッドを直接呼び出すのではなく、代表者に処理を求めるのである。代表者は処理機能は持っていないが、それを処理できる適切なメソッドを知っており、そのメソッドに処理要求を渡す。
”
会社に例えるなら「A部」の下っ端が 「B部」の下っ端にお願いするとき、「B部」の部長ならすべての方法を知っているからそこに行くという感じでしょうか。
つまり delegateとは代表者であると
検索するといろいろな例が出てきますが、コード量が増える(組織が巨大)威力が発揮しそうなのはわかります。
先駆者のサイトで勉強する
デリゲート - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
デリゲートとはメソッドを参照するための型です。 要するに、
A
という名前
のメソッドとデリゲート型の変数a
があったとすると、a = A;
というような意味合いの
事を実現するのがデリゲートです。
sample
// SomeDelegate という名前のデリゲート型を定義
using System;
delegate void SomeDelegate(int a);
class DelegateTest
{
static void Main()
{
// SomeDelegate型の変数にメソッドを代入。
SomeDelegate a = new SomeDelegate(A);
a(256); // デリゲートを介してメソッドを呼び出す。
// この例では A(256) が呼ばれる。
}
static void A(int n)
{
Console.Write("A({0}) が呼ばれました。\n", n);
}
}
A(256) が呼ばれました。
C# 2.0 からは、SomeDelegate a = A;
と言うように、メソッドからデリゲートへの暗黙の変換が出来るようになりました。
using System;
// SomeDelegate という名前のデリゲート型を定義
delegate void SomeDelegate(int a);
class DelegateTest
{
static void Main()
{
// SomeDelegate型の変数にメソッドを代入。
//SomeDelegate a = new SomeDelegate(A);
//C# 2.0 からはこれ
SomeDelegate a = A;
a(256); // デリゲートを介してメソッドを呼び出す。
// この例では A(256) が呼ばれる。
}
static void A(int n)
{
Console.Write("A({0}) が呼ばれました。\n", n);
}
}
=> イカにしか見えない splatoonに汚染されたの?
さらにこれに匿名メソッド式??を加えて、void Aを簡略化するとこうなるらしいです。
using System;
// SomeDelegate という名前のデリゲート型を定義
delegate void SomeDelegate(int a);
class DelegateTest
{
static void Main()
{
// SomeDelegate型の変数にメソッドを代入。
//SomeDelegate a = new SomeDelegate(A);
//C# 2.0 からはこれ
//SomeDelegate a = A;
SomeDelegate a = new SomeDelegate(delegate (int n) { Console.WriteLine("A({0}) が呼ばれました。\n", n); });
a(256); // この例では a(256) が呼ばれる。
}
//static void A(int n)
//{
// Console.Write("A({0}) が呼ばれました。\n", n);
//}
}
なおC# 3.0以降では、匿名メソッドの代わりにラムダ式を使えます。
デリゲート (プログラミング) - Wikipedia
using System;
// SomeDelegate という名前のデリゲート型を定義
delegate void SomeDelegate(int a);
class DelegateTest
{
static void Main()
{
// SomeDelegate型の変数にメソッドを代入。
//SomeDelegate a = new SomeDelegate(A);
//C# 2.0 からはこれ
//SomeDelegate a = A;
//SomeDelegate a = new SomeDelegate(delegate (int n) { Console.WriteLine("A({0}) が呼ばれました。\n", n); });
SomeDelegate a =(n)=> { Console.WriteLine("A({0}) が呼ばれました。\n", n); };
a(256); // この例では a(256) が呼ばれる。
}
//static void A(int n)
//{
// Console.Write("A({0}) が呼ばれました。\n", n);
//}
}
ここまできてイカちゃんマークまで到達!!
おや、なんと
Action action = () => Console.WriteLine("Hello, World!!"); イコールが()に挟まって イカが発生していて更に謎
もクリアすることができました!
Func< T >Action< T > 関数に "< > " がついていて謎
体力がつきました・・・
次回にさせてください。
今回はこれぐらいにしといてやるでゲソ
今回のソースは C# .netcore コンソール アプリケーションでコピペすれば動きます。
皆様の是非順序だてしてチャレンジ