C#でメソッド構文を書いてみる

# 1. はじめに
* C#のLINQでメソッド構文を使いたい

# 2. 数値型

## 2.1.  Where

* 抽出した条件に合致する値を取得する

```csharp
var nums = new List<int> {1, 2, 3, 4, 5, 6};
var result = nums.Where(x=>x ?=5);
Debug.Print("result=" + string.Join(",", result));
```



## 2.2. Average

* 平均値を取得する

```csharp
var result = nums.Average();
```



## 2.3.  Max

* 最大値を取得する

```csharp
var result = nums.Max();
```





## 2.4.  Min

* 最小値を取得する

```csharp
var result = nums.Min();
```



## 2.5. Sum

* 合計値を集計する

```csharp
var result = nums.Sum();
```

# 3. 文字型

## 3.1.  Average, Max, Min, Sum

* 文字列の長さの平均を集計する
* Max, Min, Sumも同じように使用できる

```csharp
string[] values = {"A","BB","CCC","DDDD","EEEE"};
var result = values.Average(x=> x.Length);
```



## 3.2.  OfType

* Tの型の値のみを取得する

```c#
Object[] objects = {1,2,"A","BB","CCC"};
// int型の値のみを取得する
var result = objects.OfType<int>();
```


# 4. カスタムクラス型

## 4.1.  Where

* 抽出した条件に合致する値を取得する

```csharp
// 商品コード、商品名、価格のカスタムクラス
var products = new List<Product>();
products.Add(new Product(10,"name",100));
products.Add(new Product(20,"name",200));
// 価格が200のもの抽出する
var results = products.Where(p=> p.Price ==200);
foreach(var val in results)
{
    Debug.print($"results: id={val.ProductId} name={val.ProductName} price={val.Price}");
}
```



## 4.2.  Select

* 必要な項目のみを取得する
* 複数項目の場合、```new{```内に項目を併記する

```csharp
// 単項目の場合
var results = products.Where(p=> p.Price ==200).Select(p=>p.ProductId);

// 単項目の場合
var results = products.Where(p=> p.Price ==200).Select(p=>　new{p.ProductId, p.ProductName});
```

# 5. リスト型

# 5.1. ForEach

* 取得したものに対してActionを記述できる

```csharp
// デバッグ出力するケース
var results = products.Where(p=> p.Price ==200).ToList();
results.ForEach(p=>Debug.Print(p.ProductName));

// リストのDTOへ追加するケース
var dtos = new List<ProductDto>();
results.ForEach(p=>dtos.Add(new ProductDto(x)));
```



## 5.2.  ToArray, ToList, ConvertAll

* ToArray: 配列に変換する
* ToList: リストに変換する
* ConvertAll: 任意の型に変換する

```csharp
// 配列に変換する
var results = products.Where(p=> p.Price ==200).ToArray();
// リストに変換する
var results = products.Where(p=> p.Price ==200).ToList();
// 任意の型に変換する1
var results = products.Where(p=> p.Price ==200).ConvertAll((x=> new ProductDto(x)));
// 任意の型に変換する2
var nums = new List<int>{1,2,3};
var results = nums.ConverAll(x=> x.ToString());
```

## 5.3.  OrderBy

* 昇順で並び替える

```csharp
// 昇順
var results = products.OrderBy(x=>x.Price);
```



## 5.4. OrderByDescending

* 昇順で並び替える

```csharp
// 降順
var results = products.OrderByDescending(x=>x.Price);
```

## 5.5. ThenBy

* OrderByで複数条件の場合に使用する

```csharp
var results = products.OrderByDescending(x=>x.Price).ThenBy(x=>x.ProductId);
```



## 5.6. GroupBy

* グループ化することができる

```csharp
// 単項目の場合
var results = products.GroupBy(x=>x.Price);
// 複数項目の場合
var results = products.GroupBy(x=>new{x.ProductId,x.Price});
```



# 6. Enumerableクラス

## 6.1. Repeat

* 指定回数で繰り返し返却する

```csharp
/// results = 5,5,5,5,5,5,5,5,5,5;
var results = Enumerable.Repeat(5,10);
```

## 6.2.  Range

* 指定した範囲で値を返却する

```csharp
/// results = 34,35,36
var results = Enumerable.Range(34,3);
```

## 6.3. SequenceEqual

* 値が同じかどうかを判定する

```csharp
// 配列の場合
string[] x = new string[] {"A","B"};
string[] y = new string[] {"A","B"};
Debug.print(x.SequenceEqual(y)); // true
Debug.print(x==y));	// false

// カスタムクラスの場合
var x = new List<Product>();
products.Add(new Product(10,"name",100));
products.Add(new Product(20,"name",200));
var y = new List<Product>();
products.Add(new Product(10,"name",100));
products.Add(new Product(20,"name",200));
Debug.print(x.SequenceEqual(y)); // false (Equalsメソッドをoverrideする必要あり)
```

* カスタムクラスのEqualsメソッドをオーバーライドするサンプル

```csharp
public override bool Equals(object obj)
{
    // パラメータがnullの場合
    if(obj == null){
        return false
    }
    
    // 型変換ができなかった場合
    var product = obj as product;
    if(product == null){
        return false;
    }
    
    // 商品IDが違う場合
    if(product.ProductId =! ProductId)
        return false;
	}

	// 商品名が違う場合
    if(product.ProductName =! ProductName)
        return false;
	}

	// 価格が違う場合
    if(product.Price =! Price)
        return false;
	}

	// 値が同じ場合
    return true;
}
```

## 6.4. Distinct

* 値を重複を削除する

```csharp
var nums[] = new int[] {1,1,2,2};
// results: 1,2
var results =　nums.Distinct();
```

## 6.5. Intersect

* 重複する値を取得する

```csharp
var x[] = new int[] {1,2,3};
var y[] = new int[] {3,4,5};

// results: 3
var results = x.Intersect(y);
```


## 6.6. Union

* どちらかにある値を取得する

```csharp
var x[] = new int[] {1,2,3};
var y[] = new int[] {3,4,5};

// results: 1,2,3,4,5
var results = x.Union(y);
```

## 6.7.  Except

* 片方のみにある値を取得する

```csharp
var x[] = new int[] {1,2,3};
var y[] = new int[] {3,4,5};

// results: 1,2
var results = x.Except(y);
// results: 4,5
var results = y.Except(x);

```

## 6.8. Skip

* 指定した回数スキップした後の値を取得する

```csharp
var nums[] = new int[] {1,2,3,4,5};

// results: 4,5
var results = x.Skip(3);
```

## 6.9. Take

* 先頭から指定した回数の値を取得する

```csharp
var nums[] = new int[] {1,2,3,4,5};

// results: 1,2,3
var results = x.Take(3);
```

## 6.10. SkipWhile

* 指定した条件までスキップした後の値を取得する

```csharp
var nums[] = new int[] {1,2,3,4,5,4,3,2,1};

// results: 3,4,5,4,3,2,1
var results = x.SkipWhile(x=> x <3);
```

## 6.11. TakeWhile

* 指定した条件までの値を取得する

```csharp
var nums[] = new int[] {1,2,3,4,5,4,3,2,1};

// results: 1,2,3,4
var results = x.TakeWhile(x=> x <5);
```

## 6.12. All

* すべて指定した条件に合致しているかを判定する

```csharp
var nums[] = new int[] {1,2,3,4,5,4,3,2,1};

// results: true
var result = x.All(x=> x>1);
// results: false
var result = x.All(x=> x>2);
```

## 6.12. Any

* 指定した条件にいずれかに合致しているかを判定する

```csharp
var nums[] = new int[] {1,2,3,4,5,4,3,2,1};

// results: true
var result = x.All(x=> x==1);
// results: false
var result = x.All(x=> x==6);
```

# 7. 参考文献
https://www.udemy.com/course/lambda02/