LoginSignup
3
1

More than 1 year has passed since last update.

C#でラムダ式を理解する

Last updated at Posted at 2023-01-21

1. はじめに

  • 見よう見まねで書いているラムダ式を最初から理解したい
  • => (ラムダ演算子:ゴーズ・トゥー)の意味を理解したい

2. 開発環境

  • Visual Studio 2022
  • .NET6
  • Windows10

3. ラムダ式を理解する前に

3.1. ラムダ式なし

  • この式を徐々にラムダ式に変えていく
var values = new string[] { "A", "BB", "CCC", "DDDDD", "EEEEE" };

var result = new List<string>();
foreach (var val in values)
{
	if (val.Length >= 3)
	{
		result.Add(val)
	}
}

Console.WriteLine(string.Join(",", result);

3.2. ラムダ式なし:共通関数

  • 共通関数を作成する
var result = GetValues(values);
Console.WriteLine(string.Join(",", result);

private string[] GetValues(String[] values)
{
	var result = new List<string>();
	foreach (var val in values)
	{
		if (val.Length >= 3)
		{
			result.Add(val)
		}
	}

	return result.ToArray();
}

3.3. ラムダ式なし:共通関数2

  • 共通関数に引数を追加する
var result = GetValues(values, 3);
Console.WriteLine(string.Join(",", result);

private string[] GetValues(String[] values, int len)
{
	var result = new List<string>();
	foreach (var val in values)
	{
		if (val.Length >= len)
		{
			result.Add(val)
		}
	}

	return result.ToArray();
}

3.4. ラムダ式なし:デリゲート

  • デリゲートを定義して式をパラメータに渡す
var result = GetValues(values, Shiki);
Console.WriteLine(string.Join(",", result);

delegate bool LenCheck(string value);

private bool Shiki(string value)
{
	return str.Length >= 3;	
}

private string[] GetValues(String[] values, LenCheck lenCheck)
{
	var result = new List<string>();
	foreach (var val in values)
	{
		if (lenCheck(val))
		{
			result.Add(val)
		}
	}

	return result.ToArray();
}

3.5. ラムダ式なし:匿名メソッド

  • デリゲートに匿名メソッドを渡す
var result = GetValues(
	values, 
	delegate (string s)
	{
		 return s.Length == 3;
	}
);
Console.WriteLine(string.Join(",", result);

delegate bool LenCheck(string value);

private string[] GetValues(String[] values, LenCheck lenCheck)
{
	var result = new List<string>();
	foreach (var val in values)
	{
		if (lenCheck(val))
		{
			result.Add(val)
		}
	}

	return result.ToArray();
}

3.6. ラムダ式なし:Predicate

  • デリゲートをPredicateに書き換える
var result = GetValues(
	values, 
	delegate (string s)
	{
		 return s.Length == 3;
	}
);

Console.WriteLine(string.Join(",", result);

delegate bool LenCheck(string value);

private string[] GetValues(String[] values, Predicate<string> predicate)
{
	var result = new List<string>();
	foreach (var val in values)
	{
		if (predicate(val))
		{
			result.Add(val)
		}
	}

	return result.ToArray();
}

4. ラムダ式の文法

4.1. C#の遍歴

  • C# 1.0 delagate
  • C# 2.0 匿名メソッド、Predicate,ジェネリック
  • C# 3.0 ラムダ式、Linq
  • C# 4.0以降 リフレクション、Task, async, awaitなど

4.2. ラムダ式の文法

// ラムダ式なし
delegate(string s)
{
	return s.Length==3;
}

// ラムダ式あり
s=> s.Length==5
  • => ラムダ演算子(ゴーズ・トゥ)の書き方
    • 左辺:パラメータ
    • 右辺:式または文
      • 右辺が式のみの場合はreturnを書かなくてよい
      • 右辺が分の場合は{},return,;が必要

4.3. パラメータ別の書き方

  • パメータなしの場合
    • ()=>Console.WriteLine("XXX")
  • パラメータ1つの場合
    • s=> s.Length==5
  • パラメータが複数の場合
    • (a,len) => a.Length==5+len
// パラメータが2つの場合
(a,len) =>
{
	if(a[0]) == 'E')
	{
		return a.Length > len;
	}
	return false;
}

// パラメータが1つの場合
var values = new string[] { "A", "BB", "CCC", "DDDDD", "EEEEE" };

var result = GetValues(
	values, 
	value => value.Length == 3
);

Console.WriteLine(string.Join(",", result);

private string[] GetValues(String[] values, Predicate<string> predicate)
{
	var result = new List<string>();
	foreach (var val in values)
	{
		if (predicate(val))
		{
			result.Add(val)
		}
	}

	return result.ToArray();
}

4.4. Func, Actionの書き方

  • Func: 戻り値がある場合
  • Ation: 戻り値がない場合
// Funcの書き方
delegate bool LenCheck(string value; int len);
Func<string, int, bool> lenCheck // 最後が戻り値

// Actionの書き方
delegate void MyCheck(string value);
Action<string>

4.5. コレクションの書き方

  • IEnumerableで使用できる
    • Where
    • Any
  • Listのみ
    • Find
    • FindAll
    • Exist
// コレクション
var values = new string[] { "A", "BB", "CCC", "DDDDD", "EEEEE" };

var result4 = values.Where(x=> x.Contains("B"));
Console.WriteLine("result:" + string.join(",", result4));
// x=> x.Contains("B").ToList()にすると即時実行できる

var result5 = values.Any(x=> x.Contains("B"));
Console.WriteLine("result:" + string.join(",", result5));

// Listしか使用できない
// Where + Firstと同じ
var result1 = values.Find(x=> x.Contains("B"));
Console.WriteLine("result:" + string.join(",", result1));

// Listしか使用できない
// Whereと同じ
var result2 = values.FindAll(x=> x.Contains("B"));
Console.WriteLine("result:" + string.join(",", result2));

// Listしか使用できない
// Anyと同じ
var result3 = values.Exist(x=> x.Contains("B"));
Console.WriteLine("result:" + string.join(",", result3));

5. 参考文献

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1