Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9308

【C#】定義済みデリゲートとラムダ式を使用し、省略された1つの式を読み解く

$
0
0

概要

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~がセットされている
image.png
右辺はどういう処理を行っているのか?デリゲートの関係性は? ▶ 分解して謎を解きます

上記のコードを分解しました 

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 >がセットされています
image.png

  • ポイント2 resultstring型
varresult=func();

デリゲートはメソッドと同じように();で実行されます
変数result には 変数func実行結果を セットしています
image.png
元の式はすべて一行にまとまっていたため、難しくみえたキャストと実行ですが
分解して変数にセットすることで何をしているか?どの値がセットされているのか?がわかりやすくなりました
分解前は名前がないFunc< string >を実行(キャスト部分は省略)();
分解後は名前があるFunc< string >を実行func();

まとめ

この式は、キャスト後のデリゲートを実行resultに結果をセットしている式である
image.png
左辺: result▶ デリゲート実行結果
右辺: ((Func<string>)キャスト(()=>{省略})();デリゲートを実行

省略するメリット・デメリット

メリット
コードを短くできる・余計な変数名を考えなくて良い
デメリット
ある程度の知識がないと読めない

最後に

読めるようになった今、この書き方は割とイケてるのではないかと思っています
括弧が多いため若干の不格好はありますが・・・!どなたかの参考になれば嬉しいです👀
記事内のサンプルコードはGitHubにあげています ▶ CsharpDelegateCastSample

この記事はQiita初投稿記事となります
読みづらいところもあると思いますが、最後まで見て頂きありがとうございました


Viewing all articles
Browse latest Browse all 9308