C# 省略形シリーズもいよいよ第6弾。最初は全3回って言ってたのに。
今回はちょっと視点を変えて、LINQとラムダ式の中に潜む「省略形」にフォーカスします。
if
や switch
とは少し違いますが、省略して書ける・短く書けるという意味では、実はこの世界にも“誘惑”がたくさん潜んでいるのです。
ラムダ式の基礎:型もreturnも書かなくていい?
ラムダ式とは、名前のない関数を簡潔に記述するための表記法です。無名関数とも呼ばれ、従来の関数定義のように名前を付ける必要がなく、引数と処理内容をまとめて記述できます。
まずは基本のラムダ式から。
🗂️ 普通に書くとこう(delegate式)
Func<int, int> square = delegate(int x)
{
return x * x;
};
このコードは 「整数を受け取って、その2乗を返す関数」 を変数に代入している例です。
この関数を square
という変数に代入していますので、あとでこう使えます。
int result = square(5); // → 25が代入される
一昔前まではこれが主流でした。
こんなラムダくんも省略することができます。
✂️ 省略するとこう(ラムダ式)
Func<int, int> square = x => x * x;
- 型推論OK(
int
書かなくてよし) - returnも省略OK(式が1つなら return 要らず)
- さらに波カッコ
{}
も省略OK
慣れてくると、こちらのほうが断然読みやすく感じます。
LINQのメソッドチェーン:WhereやSelectの省略術
LINQ(統合言語クエリ)とは、コレクション(配列やList、Dictionaryなど)の要素を処理するメソッドを集めたライブラリのことです。
LINQのクエリでも、ラムダ式の省略形が大活躍します。
🗂️ 普通に書くとこう
List<int> evens = new List<int>();
foreach (var n in numbers)
{
if (n % 2 == 0)
{
evens.Add(n);
}
}
このコードは 「リスト numbers
の中から偶数だけを取り出して、新しいリスト evens
に追加する」という処理をしています。if (n % 2 == 0)
で「n
が偶数かどうか」をチェックしています。%
は余りを求める演算子です。
処理としてはシンプル。でもコードが長くなりがち。
✂️ 省略するとこう(LINQ+ラムダ)
var evens = numbers.Where(n => n % 2 == 0).ToList();
Where(...)
は LINQ(リンク) のメソッドのひとつで、「条件に合う要素だけを抽出する」働きをします。Where
は「フィルター処理」を担当します。
- 条件に合う要素をそのまま抽出
- メソッドチェーンで完結
- foreachもAddも不要
たった一行で同じことができます。
「読む」より「読む前にわかる」感じに近づけるのがLINQの強みですね。
Selectで加工も一行
🗂️ 普通に書くとこう
List<int> doubled = new List<int>();
foreach (var n in numbers)
{
doubled.Add(n * 2);
}
このコードは 「リスト numbers
の各要素を2倍にして、新しいリスト doubled
に追加する」という処理をしています。
✂️ 省略するとこう(Select)
var doubled = numbers.Select(n => n * 2).ToList();
Select(...)
は LINQ の中でもよく使われるメソッドで、「要素を変換する」働きをします。「1つの要素 → 新しい値」への変換を行います。Select
は「1対1の変換を行うツール」と覚えておくと理解しやすいです!
このコードによって、1つ1つ処理するよりも「ワイは変換したいだけなんじゃ」という意図が明確になります。
読みやすく、メンテナンスもしやすくなります。
無名型、メソッドグループ、省略の極み
C#にはまだ他にも、「これ、実は省略できる」パターンがあります。
無名型(匿名型)
var data = people.Select(p => new { p.Name, p.Age });
このコードは リスト people
の各要素から「名前」と「年齢」だけを抜き出して、新しい形のデータを作る」 処理です。Selectは先程でてきましたね。「1対1の変換ツール」です。
new
の後に型名を書かずに済む- 特にクエリ結果や一時的なデータ構造に便利
メソッドグループ
var lengths = words.Select(GetLength); // GetLength(string) => int
このコードは、words
という文字列リストの各要素に対して GetLength
というメソッドを適用し、その結果(長さ)をリストとして取得するものです。
↓これはこうも書けます。
var lengths = words.Select(w => GetLength(w)); // 同じ意味
- 引数をそのまま渡すだけなら、
メソッド名
だけでOK - メソッドグループ変換と呼ばれる小技
まとめ:省略=短くすることではなく、意図を明確にすること
処理内容 | 普通の書き方 | 省略形 |
---|---|---|
匿名関数 | delegate (...) { return ... } | (...) => ... |
要素の抽出(filter) | foreach + if + Add | Where(...) |
要素の変換(map) | foreach + 加工 + Add | Select(...) |
引数をそのまま渡す | x => SomeMethod(x) | SomeMethod (メソッドグループ) |
「短い=正義」ではなく、伝わるかどうかが大事。
読みやすさと省略のバランスが取れるようになると、LINQやラムダ式は一気に武器になります。
次回予告:省略の終着点?記録(record)と式メンバー、完全に “書かないC#” へ
次回は、C#のさらに先へ。
record型、式メンバー、init専用プロパティなど、構造自体を簡潔に書ける構文を紹介します。
「書く手間」ではなく「書かなくても伝わる設計」を目指すC#の進化を一緒に見ていきましょう。
それではまた、省略と明快さが共存するコードの世界でお会いしましょう。