[C#] switch文で定数以外を使用する方法
C#のswitch文は通常、定数値を使用して分岐を行いますが、C# 7.0以降ではパターンマッチングを利用して定数以外の条件を扱うことができます。
具体的には、switch
式やwhen
キーワードを用いることで、より柔軟な条件分岐が可能です。
例えば、switch
式を使ってオブジェクトの型やプロパティに基づいて分岐したり、when
キーワードを用いて条件式を追加することで、特定の条件を満たす場合にのみ特定のケースを実行することができます。
これにより、従来の定数ベースのswitch文よりも複雑なロジックを簡潔に記述できます。
switch文の基本構造
C#のswitch文は、特定の変数や式の値に基づいて、複数の分岐を実行するための制御構造です。
switch文を使用することで、if-else文よりもコードを簡潔に記述できる場合があります。
ここでは、switch文の基本的な使い方、定数を用いた例、そして制限事項について説明します。
switch文の基本的な使い方
switch文は、以下のような構文で記述します。
switch (式)
{
case 値1:
// 値1に対する処理
break;
case 値2:
// 値2に対する処理
break;
default:
// どのcaseにも一致しない場合の処理
break;
}
式
は評価される対象で、整数型や文字列型などが使用されます。case
は、式
の値と一致する場合に実行されるブロックを示します。default
は、どのcase
にも一致しない場合に実行されるブロックです。
定数を用いたswitch文の例
switch文では、case
ラベルに定数を使用する必要があります。
以下は、整数型の定数を用いた例です。
using System;
class Program
{
static void Main()
{
int number = 2; // 評価する数値
switch (number)
{
case 1:
Console.WriteLine("数値は1です。");
break;
case 2:
Console.WriteLine("数値は2です。");
break;
case 3:
Console.WriteLine("数値は3です。");
break;
default:
Console.WriteLine("数値は1から3の範囲外です。");
break;
}
}
}
数値は2です。
この例では、変数number
の値が2
であるため、case 2:
のブロックが実行されます。
switch文の制限事項
switch文にはいくつかの制限事項があります。
以下に主なものを示します。
case
ラベルには定数しか使用できません。
変数や式を直接使用することはできません。
case
ラベルの値は一意でなければなりません。
同じ値を持つ複数のcase
ラベルを持つことはできません。
switch
文で使用できるデータ型は、整数型、文字列型、列挙型などに限られます。
浮動小数点数型や複雑なオブジェクト型は使用できません。
これらの制限を理解することで、switch文を効果的に活用することができます。
パターンマッチングの導入
パターンマッチングは、C#における強力な機能で、オブジェクトの型や構造に基づいて条件分岐を行うことができます。
これにより、コードの可読性と保守性が向上し、より直感的なプログラミングが可能になります。
ここでは、パターンマッチングの基本、C# 7.0での進化、そして基本的な構文について説明します。
パターンマッチングとは
パターンマッチングは、オブジェクトの型やプロパティの値に基づいて、特定の処理を実行するための手法です。
従来のswitch文やif文では、単純な値の比較しかできませんでしたが、パターンマッチングを用いることで、より複雑な条件を簡潔に記述できます。
C# 7.0でのパターンマッチングの進化
C# 7.0では、パターンマッチングが導入され、switch文やis演算子での型チェックが強化されました。
これにより、以下のような機能が追加されました。
- 型パターン: オブジェクトの型をチェックし、その型に基づいて処理を行う。
- 定数パターン: 定数と比較して一致するかどうかを判断する。
- varパターン: 任意の型のオブジェクトを受け入れ、変数に代入する。
これらの機能により、コードの柔軟性が大幅に向上しました。
パターンマッチングの基本構文
パターンマッチングを使用する基本的な構文は以下の通りです。
using System;
class Program
{
static void Main()
{
object obj = "こんにちは"; // 任意のオブジェクト
switch (obj)
{
case int i:
Console.WriteLine($"整数: {i}");
break;
case string s:
Console.WriteLine($"文字列: {s}");
break;
default:
Console.WriteLine("未知の型");
break;
}
}
}
文字列: こんにちは
この例では、変数obj
の型に基づいてswitch文が実行されます。
obj
がstring型
であるため、case string s:
のブロックが実行され、文字列が出力されます。
パターンマッチングを活用することで、型や構造に基づく条件分岐を簡潔に記述でき、コードの可読性が向上します。
switch式の活用
C# 8.0で導入されたswitch式は、switch文の機能をより簡潔に記述できるようにしたものです。
switch式を使用することで、条件分岐の結果を直接変数に代入したり、式として使用することが可能になります。
ここでは、switch式の基本構文、switch文との違い、そして具体的な使用例について説明します。
switch式の基本構文
switch式は、以下のような構文で記述します。
var result = 式 switch
{
パターン1 => 結果1,
パターン2 => 結果2,
_ => デフォルト結果
};
式
は評価される対象で、switch文と同様に整数型や文字列型などが使用されます。パターン
は、式
の値に基づいて一致を確認する条件です。結果
は、パターンが一致した場合に返される値です。_
はデフォルトのパターンで、どのパターンにも一致しない場合に使用されます。
switch式とswitch文の違い
switch式とswitch文にはいくつかの違いがあります。
以下に主な違いを示します。
特徴 | switch式 | switch文 |
---|---|---|
記述方法 | 式として記述 | 文として記述 |
結果の代入 | 直接変数に代入可能 | 変数に代入するには別途処理が必要 |
簡潔さ | より簡潔に記述可能 | より冗長になる場合がある |
switch式は、結果を直接変数に代入できるため、コードがより簡潔になります。
switch式を用いた例
以下は、switch式を用いた具体的な例です。
using System;
class Program
{
static void Main()
{
int number = 3; // 評価する数値
string result = number switch
{
1 => "数値は1です。",
2 => "数値は2です。",
3 => "数値は3です。",
_ => "数値は1から3の範囲外です。"
};
Console.WriteLine(result);
}
}
数値は3です。
この例では、変数number
の値に基づいてswitch式が評価され、結果が変数result
に代入されます。
number
が3
であるため、"数値は3です。"
が出力されます。
switch式を使用することで、条件分岐の結果を直接変数に代入でき、コードがより簡潔で読みやすくなります。
whenキーワードの利用
C#のwhenキーワードは、switch文やswitch式において、より詳細な条件を指定するために使用されます。
これにより、単純な値の一致だけでなく、追加の条件を組み合わせた柔軟な条件分岐が可能になります。
ここでは、whenキーワードの基本構文、条件付きswitch文の例、そして複数条件を用いた活用例について説明します。
whenキーワードの基本構文
whenキーワードは、switch文やswitch式の各caseラベルに追加の条件を指定するために使用されます。
基本構文は以下の通りです。
switch (式)
{
case パターン when 条件:
// 条件がtrueの場合の処理
break;
default:
// どのcaseにも一致しない場合の処理
break;
}
パターン
は、switch文のcaseラベルで指定する基本的な一致条件です。条件
は、パターンが一致した場合にさらに評価される条件式です。
whenを用いた条件付きswitch文
whenキーワードを用いることで、switch文に追加の条件を組み込むことができます。
以下は、whenを用いた条件付きswitch文の例です。
using System;
class Program
{
static void Main()
{
int number = 5; // 評価する数値
switch (number)
{
case int n when n > 0:
Console.WriteLine("数値は正の数です。");
break;
case int n when n < 0:
Console.WriteLine("数値は負の数です。");
break;
default:
Console.WriteLine("数値はゼロです。");
break;
}
}
}
数値は正の数です。
この例では、変数number
が正の数であるため、case int n when n > 0:
のブロックが実行されます。
複数条件を用いたwhenの活用例
whenキーワードを用いることで、複数の条件を組み合わせた柔軟な条件分岐が可能です。
以下は、複数条件を用いた活用例です。
using System;
class Program
{
static void Main()
{
int number = 15; // 評価する数値
switch (number)
{
case int n when n > 0 && n % 3 == 0:
Console.WriteLine("数値は正の数で、3の倍数です。");
break;
case int n when n > 0 && n % 5 == 0:
Console.WriteLine("数値は正の数で、5の倍数です。");
break;
default:
Console.WriteLine("数値は条件に一致しません。");
break;
}
}
}
数値は正の数で、3の倍数です。
この例では、変数number
が15
であり、正の数かつ3の倍数であるため、case int n when n > 0 && n % 3 == 0:
のブロックが実行されます。
whenキーワードを活用することで、switch文やswitch式において、より詳細で柔軟な条件分岐を実現できます。
型パターンの使用
型パターンは、C#のパターンマッチング機能の一部で、オブジェクトの型に基づいて条件分岐を行うための手法です。
これにより、オブジェクトの型を確認し、その型に応じた処理を簡潔に記述することができます。
ここでは、型パターンの基本、型パターンを用いたswitch文の例、そしてその利点と注意点について説明します。
型パターンとは
型パターンは、オブジェクトが特定の型であるかどうかを確認し、その型に基づいて処理を行うためのパターンです。
型パターンを使用することで、型チェックとキャストを一度に行うことができ、コードの冗長性を減らすことができます。
型パターンを用いたswitch文の例
型パターンを用いることで、switch文でオブジェクトの型に基づく条件分岐を行うことができます。
以下は、型パターンを用いたswitch文の例です。
using System;
class Program
{
static void Main()
{
object obj = "こんにちは"; // 任意のオブジェクト
switch (obj)
{
case int i:
Console.WriteLine($"整数: {i}");
break;
case string s:
Console.WriteLine($"文字列: {s}");
break;
case null:
Console.WriteLine("オブジェクトはnullです。");
break;
default:
Console.WriteLine("未知の型");
break;
}
}
}
文字列: こんにちは
この例では、変数obj
がstring型
であるため、case string s:
のブロックが実行され、文字列が出力されます。
型パターンの利点と注意点
型パターンを使用することにはいくつかの利点があります。
- コードの簡潔化: 型チェックとキャストを一度に行うことができ、コードが簡潔になります。
- 可読性の向上: 型に基づく処理が明示的に記述されるため、コードの可読性が向上します。
- 安全性の向上: 型が一致しない場合の処理を明示的に記述できるため、型エラーを防ぐことができます。
しかし、型パターンを使用する際には注意が必要です。
- 型の不一致: 型が一致しない場合の処理を忘れずに記述する必要があります。
例:default
ケースを用意する。
- パフォーマンス: 型チェックが頻繁に行われる場合、パフォーマンスに影響を与える可能性があります。
型パターンを適切に活用することで、型に基づく条件分岐を効率的に行うことができます。
プロパティパターンの利用
プロパティパターンは、C#のパターンマッチング機能の一部で、オブジェクトのプロパティに基づいて条件分岐を行うための手法です。
これにより、オブジェクトの内部状態を確認し、その状態に応じた処理を簡潔に記述することができます。
ここでは、プロパティパターンの基本構文、プロパティパターンを用いたswitch文の例、そしてその応用について説明します。
プロパティパターンの基本構文
プロパティパターンは、オブジェクトのプロパティを直接参照し、その値に基づいて条件を指定するためのパターンです。
基本構文は以下の通りです。
switch (オブジェクト)
{
case 型 { プロパティ: 値 }:
// プロパティが指定された値の場合の処理
break;
default:
// どのパターンにも一致しない場合の処理
break;
}
型
は、オブジェクトの型を指定します。プロパティ
は、オブジェクトのプロパティ名を指定します。値
は、プロパティが一致するかどうかを確認するための値です。
プロパティパターンを用いたswitch文の例
プロパティパターンを用いることで、switch文でオブジェクトのプロパティに基づく条件分岐を行うことができます。
以下は、プロパティパターンを用いたswitch文の例です。
using System;
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main()
{
var person = new Person { Name = "太郎", Age = 30 }; // Personオブジェクトの作成
switch (person)
{
case Person { Age: 30 }:
Console.WriteLine("30歳の人です。");
break;
case Person { Age: 20 }:
Console.WriteLine("20歳の人です。");
break;
default:
Console.WriteLine("年齢が特定の範囲外です。");
break;
}
}
}
30歳の人です。
この例では、person
オブジェクトのAge
プロパティが30
であるため、case Person { Age: 30 }:
のブロックが実行されます。
プロパティパターンの応用
プロパティパターンは、複数のプロパティを組み合わせた条件分岐や、ネストされたオブジェクトのプロパティを参照する場合にも応用できます。
以下は、プロパティパターンの応用例です。
using System;
class Address
{
public string City { get; set; }
}
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Address Address { get; set; }
}
class Program
{
static void Main()
{
var person = new Person { Name = "太郎", Age = 30, Address = new Address { City = "東京" } }; // Personオブジェクトの作成
switch (person)
{
case Person { Age: 30, Address: { City: "東京" } }:
Console.WriteLine("30歳で東京に住んでいる人です。");
break;
case Person { Age: 20, Address: { City: "大阪" } }:
Console.WriteLine("20歳で大阪に住んでいる人です。");
break;
default:
Console.WriteLine("条件に一致しません。");
break;
}
}
}
30歳で東京に住んでいる人です。
この例では、person
オブジェクトのAge
プロパティが30
で、Address.City
プロパティが"東京"
であるため、case Person { Age: 30, Address: { City: "東京" } }:
のブロックが実行されます。
プロパティパターンを活用することで、オブジェクトの内部状態に基づく柔軟な条件分岐を実現できます。
switch文の応用例
switch文は、基本的な条件分岐だけでなく、複雑な条件やオブジェクトの型に基づく分岐、データの検証など、さまざまな応用が可能です。
ここでは、switch文を用いた複雑な条件分岐の実装、オブジェクトの型に基づく分岐、データの検証について説明します。
複雑な条件分岐の実装
switch文は、複数の条件を組み合わせた複雑な分岐を実装するのに適しています。
以下は、複雑な条件分岐を実装した例です。
using System;
class Program
{
static void Main()
{
int score = 85; // 評価するスコア
string grade = score switch
{
int n when n >= 90 => "A",
int n when n >= 80 => "B",
int n when n >= 70 => "C",
int n when n >= 60 => "D",
_ => "F"
};
Console.WriteLine($"スコア: {score}, 評価: {grade}");
}
}
スコア: 85, 評価: B
この例では、スコアに基づいて評価を決定するために、複数の条件を組み合わせたswitch式を使用しています。
オブジェクトの型に基づく分岐
switch文は、オブジェクトの型に基づく分岐を行うこともできます。
以下は、オブジェクトの型に基づく分岐の例です。
using System;
class Animal { }
class Dog : Animal { }
class Cat : Animal { }
class Program
{
static void Main()
{
Animal animal = new Dog(); // Animalオブジェクトの作成
switch (animal)
{
case Dog:
Console.WriteLine("これは犬です。");
break;
case Cat:
Console.WriteLine("これは猫です。");
break;
default:
Console.WriteLine("未知の動物です。");
break;
}
}
}
これは犬です。
この例では、animal
オブジェクトの型に基づいてswitch文が実行され、Dog型
であるため、case Dog:
のブロックが実行されます。
データの検証とswitch文
switch文は、データの検証にも利用できます。
以下は、データの検証を行う例です。
using System;
class Program
{
static void Main()
{
string input = "12345"; // 検証するデータ
bool isValid = input switch
{
string s when s.Length == 5 && int.TryParse(s, out _) => true,
_ => false
};
Console.WriteLine($"入力データ: {input}, 検証結果: {(isValid ? "有効" : "無効")}");
}
}
入力データ: 12345, 検証結果: 有効
この例では、入力データが5桁の整数であるかどうかを検証するためにswitch式を使用しています。
input
が5桁の整数であるため、true
が返されます。
switch文を応用することで、複雑な条件分岐や型に基づく処理、データの検証を効率的に行うことができます。
まとめ
この記事では、C#におけるswitch文の基本構造から、パターンマッチングやswitch式、whenキーワード、型パターン、プロパティパターンの利用方法までを詳しく解説しました。
これらの機能を活用することで、より柔軟で効率的な条件分岐を実現し、コードの可読性と保守性を向上させることが可能です。
ぜひ、実際のプログラミングにおいてこれらのテクニックを試し、C#での開発をさらに快適に進めてみてください。