概要
C#初学者をさまよい続けるこの頃・・・
なんとなくで書いていたコード「定義済みデリゲートとラムダ式を使用し、省略された1つの式」を
ようやく理解できたので、共有したいと思います。
C#を学習し、以下の知識がある初学者向けの記事になります
- 変数への代入
- 明示的な変換(キャスト)
- ラムダ式
- デリゲート(定義済みデリゲート)
定義済みデリゲートとラムダ式を使用し、省略された1つの式とは
こんなの
publicvoidDelegateSample1(){varresult=((Func<int,int,int,string>)((stock,quantity,costprice)=>{varsales=stock*quantity;//売上高varcostofsales=costprice*quantity;//売上原価returnstring.Format("粗利は ({0}-{1}) で求めることができます:{2}",sales,costofsales,sales-costofsales);}))(1500,5,1000);Console.WriteLine(result);Console.ReadKey();}
これも
publicvoidDelegateSample3(){varresult=((Func<DateTime,string>)(today=>{varlastweek=today.AddDays(-7);returnstring.Format("{0}から一週間前の日時は{1}です",today.ToShortDateString(),lastweek.ToShortDateString());}))(DateTime.Today);Console.WriteLine(result);Console.ReadKey();}
詳しく解説
これを解説します👀 実行すると現在時刻がコンソールに表示される簡単なコードです
※このコードはデリゲート/ラムダ式を介さず直接値をセットできますが、できるだけ簡素にしたかったので
publicvoidDelegateCast1(){varresult=((Func<string>)(()=>{vardate=DateTime.Now.ToShortDateString();//日付vardayOfWeek=DateTime.Now.DayOfWeek;//曜日returnstring.Format("現在時刻は:{0} です({1})",date,dayOfWeek);}))();Console.WriteLine(result);Console.ReadKey();}
どういう結果が返ってくる?var result
▶ 右辺のラムダ式内 return string.Format~
がセットされている
右辺はどういう処理を行っているのか?デリゲートの関係性は? ▶ 分解して謎を解きます
上記のコードを分解しました
publicvoidDelegateCast2(){/*double型10.00123をint型に変換*/vari=(int)10.00123;/*ラムダ式をFunc<string>に変換*/varfunc=(Func<string>)(()=>{vardate=DateTime.Now.ToShortDateString();//日付vardayOfWeek=DateTime.Now.DayOfWeek;//曜日returnstring.Format("現在時刻は:{0} です({1})",date,dayOfWeek);});varresult=func();Console.WriteLine(result);Console.ReadKey();}
※解説用にvar i = (int) 10.00123;
を追加しました
- ポイント1 以下2つのコードは両方とも キャスト(型変換)を実行している
vari=(int)10.00123;varfunc=(Func<string>)(()=>{省略});
式内の()
が多く、私の頭はよくバグるのですが・・・ よく見るとキャストの()
が浮かんでくると思います
変数funcには ラムダ式をキャストした Func< string >がセットされています
- ポイント2
result
は string型
varresult=func();
デリゲートはメソッドと同じように();
で実行されます
変数result には 変数funcの 実行結果を セットしています
元の式はすべて一行にまとまっていたため、難しくみえたキャストと実行ですが
分解して変数にセットすることで何をしているか?どの値がセットされているのか?がわかりやすくなりました
分解前は名前がないFunc< string >を実行▶ (キャスト部分は省略)();
分解後は名前があるFunc< string >を実行▶ func();
まとめ
この式は、キャスト後のデリゲートを実行し result
に結果をセットしている式である
左辺: result
▶ デリゲート実行結果
右辺: ((Func<string>)
◀ キャスト▶ (()=>{省略})
();
◀ デリゲートを実行
省略するメリット・デメリット
メリット
コードを短くできる・余計な変数名を考えなくて良い
デメリット
ある程度の知識がないと読めない
最後に
読めるようになった今、この書き方は割とイケてるのではないかと思っています
括弧が多いため若干の不格好はありますが・・・!どなたかの参考になれば嬉しいです👀
記事内のサンプルコードはGitHubにあげています ▶ CsharpDelegateCastSample
この記事はQiita初投稿記事となります
読みづらいところもあると思いますが、最後まで見て頂きありがとうございました