restofwaterimpのぎじゅつMemo

SIerに所属。企画から運用まで幅広くやってます。C#中心に書いてます。

【C#】C#プログラミングのイディオム(3章) ラムダ式とLINQの基礎と1章(プログラミングの基礎)

図書館で本を借りて、

 

3章はラムダ式LINQについて。

 

何気に、LINQを使っていたが、言語の進化の歴史については知らなかったので、そうだったんだ!という感じです。

 

この章ではラムダ式以前と以後について説明されております。

経緯は知らなかったので、メモメモ・・

 

1. メソッドに普通に引数を渡す

// 配列を引数に受け取るCountメソッド
class Step02 {
  public void Do() {
    var numbers = new { 5, 3, 9, 6, 7, 5, 8, 1, 0, 5, 10, 4 };
    var count = Count(numbers, 5);
    Console.WriteLine(count);
  }
 
  public int Count(int numbers, int num) {
    int count = 0;
    foreach (var n in numbers) {
      if (n == num)
        count++;
       }
      return count;
  }

}

 2. デリゲートによる実現

class Step04 {
public delegate bool Judgement(int value); //delegateの指定

 
public void Do() {
var numbers = new { 5, 3, 9, 6, 7, 5, 8, 1, 0, 5, 10, 4 };
var count = Count(numbers, IsEven);
Console.WriteLine(count);
}
 
public bool IsEven(int n) {
return n % 2 == 0;
}

public int Count(int numbers, Judgement judge) {
int count = 0;
foreach (var n in numbers) {
if (judge(n) == true)
count++;
}
return count;
}
}

 

3. 匿名メソッドの利用

class Step05 {
public int Count(int numbers, Predicate<int> judge) {
int count = 0;
foreach (var n in numbers) {
if (judge(n) == true)
count++;
}
return count;
}
 
public void Do() {
var numbers = new { 5, 3, 9, 6, 7, 5, 8, 1, 0, 5, 10, 4 };
var count = Count(numbers, delegate (int n) { return n % 2 == 0; });
Console.WriteLine(count);
}
}

 

4. ラムダ式

 

3でいう、Countメソッドを次のように変えることができます。

4-1 まずは、そのままべたに書く

public void Step0() {
var numbers = new { 5, 3, 9, 6, 7, 5, 8, 1, 0, 5, 10, 4 };
Predicate<int> judge =
(int n) => {
if (n % 2 == 0)
return true;
else
return false;
};
var count = Count(numbers, judge);
Console.WriteLine(count);
}
 
4-2.変数judgeを利用せず、そのままCountの引数に設定する

public void Step1() {
var numbers = new { 5, 3, 9, 6, 7, 5, 8, 1, 0, 5, 10, 4 };
var count = Count(numbers,
(int n) => {
if (n % 2 == 0)
return true;
else
return false;
}
);
Console.WriteLine(count);
}
 
4-3.if文の戻り値がboolなので、簡略化することができる

public void Step2() {
var numbers = new { 5, 3, 9, 6, 7, 5, 8, 1, 0, 5, 10, 4 };
var count = Count(numbers, (int n) => { return n % 2 == 0; });
Console.WriteLine(count);

}
 
4-4.ラムダ式の{}内が1文の場合、{}とreturnが省略可能

public void Step3() {
var numbers = new { 5, 3, 9, 6, 7, 5, 8, 1, 0, 5, 10, 4 };
var count = Count(numbers, (int n) => n % 2 == 0);
Console.WriteLine(count);

}
 
4-5.ラムダ式は引数の型を省略できる

public void Step4() {
var numbers = new { 5, 3, 9, 6, 7, 5, 8, 1, 0, 5, 10, 4 };
var count = Count(numbers, (n) => n % 2 == 0);
Console.WriteLine(count);

}
 
4-6.ラムダ式は引数が1つの場合、()を省略できる

public void Step5() {
var numbers = new { 5, 3, 9, 6, 7, 5, 8, 1, 0, 5, 10, 4 };
var count = Count(numbers, n => n % 2 == 0);
Console.WriteLine(count);
}

 

 

ラムダ式でかけるようになってから、delegateや匿名メソッドを活用して、「どうやって書こう」から、ラムダ式ですっきりかけるので、「何を書こう」に変わりました。

 

確かに、ラムダ式便利なんですよね。これあが実現されたLINQ to Objectを利用すれば、変数に対して、SQLっぽく扱えるので。以前みたいに、ゴリゴリコードをかかなくてよくなりましたから。

 

LINQ to Objectsの使い方

・System.Collections.Generic

・System.Linq

名前空間を指定します。

 

例えば。

 

   var names = new List<string>{
       "America", "Brazil", "Italia", "China", "Japan"
       };

   IEnumerable<string> query = names.Where(x => x.Length <= 5);

 

クエリの実行 | Microsoft Docs

 

利用する際、リンク演算子が「即時実行」なのか「遅延実行」なのかを知っておく必要があります。

演算子を定義した時の値で評価するのか、演算子を利用する場合の値で評価するのかの違いです。

 

即時実行したいのに、遅延実行で記載していると、取得したい値が取得できなかったりします。

 

---------------------------------------------

2020/10/24 追加  1章の話

 

 class と struct

 

クラスは参照型、structは値型となる。

参照型はヒープ領域、値型はスタック領域に値が保持される

 

私自身、structを使っているプログラムをほとんど見たことがない。

メモリを効率的に使うということで、小さい値ならstructを利用するほうがいい。

大きい値を利用する倍、ポインタで参照を利用するclassをとなるが・・・。

書籍に記載の通り、structは見たことないんですよね。使っているのを。

 

ポインタとメモリと型(構造体)の関係 (2) - C言語 - 碧色工房

 

 

 

▪️学習している書籍