省略形シリーズ、今回はif分からちょっと角度を変えて、「分岐」に注目してみます。
複雑な条件分岐が必要になると、ついif文が連打されがちですが、switch式やパターンマッチングを使えば、スッキリ・スマートに書けます。
そしてそのswitch式すら省略して記述できることはご存知でしょうか?
今回はその書き換え例を見ながら、地味に便利なこの機能たちを紹介していきます。
switch式を省略する
C# 8.0以降で使える switch式。
これまでの switch { case }
よりも、式ベースで書けるのでかなり柔軟です。
🗂️ 普通バージョン
string GetFruitColor(string fruit)
{
switch (fruit)
{
case "apple":
return "red";
case "banana":
return "yellow";
case "grape":
return "purple";
default:
return "unknown";
}
}
string fruit の値に応じて処理をスイッチするいつものやつ。
書き慣れてはいるけど、どこか「型にはまった感」がありますね。
✂️ 省略したバージョン
string GetFruitColor(string fruit) => fruit switch
{
"apple" => "red",
"banana" => "yellow",
"grape" => "purple",
_ => "unknown"
};
式として書けるので、よりコンパクト。switch
が「式」になっただけで、なぜか知的に見えるのは気のせいでしょうか。(気のせいです
パターンマッチングを省略する
C# 7.0以降、パターンマッチングが使えるようになり、switch
や is
演算子のパワーがかなり強化されました。
型チェック+キャストする方法を見てみましょう。
🗂️ 普通バージョン
if (obj is Cat)
{
var cat = (Cat)obj;
cat.Meow();
}
obj が Cat型 なら Meow() を実行。
古典的な型チェック+キャスト。C#歴の長い人にはおなじみですが、これも省略できます。
✂️ 省略バージョン
if (obj is Cat cat)
{
cat.Meow();
}
is
に変数名をつけることで、キャストと宣言を同時に行えます。
地味ですが、日常のコードを少しだけ快適にしてくれます。
🔍 応用編:switch式 × パターンマッチング
string DescribeAnimal(object animal) => animal switch
{
Cat c => $"Cat: {c.Name}",
Dog d => $"Dog: {d.Breed}",
null => "No animal",
_ => "Unknown creature"
};
この DescribeAnimal
メソッドの処理内容は、引数として渡された animal
オブジェクトの型を調べて、それに応じた文字列を返すというものです。
この switch式
では、animal
の型と状態に応じて、次のように分岐します。
animal
がCat
型の場合- 変数
c
にキャストされる(Cat c
の部分)。 - その
Name
プロパティを使って"Cat: 名前"
という文字列を返す。
animal = new Cat { Name = "Tama" }
→ 戻り値:"Cat: Tama"
- 変数
animal
がDog
型の場合Dog d
にキャストされて、Breed
プロパティが使われる。"Dog: 犬種"
という文字列を返す。
animal = new Dog { Breed = "Shiba" }
→ 戻り値:"Dog: Shiba"
animal
がnull
の場合- 文字列
"No animal"
を返す。
- 文字列
- それ以外(
Cat
でもDog
でもなく、null でもない場合)_
(ワイルドカード)にマッチし、"Unknown creature"
を返す。
animal = new Hamster()
→"Unknown creature"
補足ポイントとしては・・・
switch式
を使っているので、式全体がそのまま戻り値になります(=>
の形)。- 各行で「型チェック + キャスト + 処理」が一気に行われていて、非常にコンパクトです。
- nullチェックも
switch
のパターンの一部として含まれているのが特徴的です。
このように switch式
にパターンマッチングを組み合わせることで、かなり柔軟な分岐が可能になります。
インスタンスの型に応じて処理を分けたいときなどに活躍します。
まとめ
処理内容 | 普通の書き方 | モダンな書き方 |
---|---|---|
値による分岐(return) | switch { case ... return ... } | switch式 |
型チェックとキャスト | if (x is T) var t = (T)x; | if (x is T t) |
型による分岐処理 | if / else if / cast の連打 | switch式 + パターンマッチング |
コード量が減るだけでなく、意図が読みやすくなるのもこの書き方のメリットです。
次回予告:if文の完全体?when節とパターンの合わせ技
次回は、パターンマッチングの続編として when
節との組み合わせや、さらに踏み込んだ 「条件付きパターン」 を紹介していく予定です。
分岐処理がどこまで表現力を持てるのか、一緒に見ていきましょう。
それではまた次回、より洗練された分岐の世界でお会いしましょう。