Tip
この記事は、少なくとも 1 つのプログラミング言語を既に知っており、C# を学習している開発者向けの 基礎 セクションの一部です。 パターンが初めて使用される場合は、パターン マッチングの概要 から始めます。 完全な言語ルールについては、言語リファレンス のリレーショナル パターン と 論理パターン を参照してください。
リレーショナル パターンと論理パターンでは、範囲、代替手段、除外について説明します。 次の方法では、それらを組み合わせて温度を分類します。
static string ClassifyTemperature(int temperature) =>
temperature switch
{
< 0 => "Below freezing",
>= 18 and <= 24 => "Comfortable",
(>= 0 and < 10) or > 30 => "Far outside the comfortable range",
_ => "Cool or warm"
};
temperature式はパターン入力です。 C# はそれを 1 回評価し、各スイッチ アームは結果の値をテストします。 アームは以下のテストを実施します。
-
< 01 つの境界をテストします。 -
>= 18 and <= 24範囲をテストします。 -
(>= 0 and < 10) or > 302 つの代替範囲をテストします。
この記事では、パターンと命令型の条件の両方を示します。これにより、各フォームを学習し、同じ決定を表す方法を比較できます。 1 つの条件は、どちらの形式でも似ています。 パターンを使用すると、結果の横に選択肢を維持することで、一連の関連ブランチを読みやすくすることができます。 コードを理解しやすくするフォームを選択します。
リレーショナル パターンと値を比較する
リレーショナル パターンでは、<、>、<=、または>=を使用して、そのパターン入力をコンパイル時定数と比較します。
コンパイル時定数は、プログラムのコンパイル中にコンパイラが評価できる値です。 数値リテラルと文字リテラル、および互換性のある数値型または文字型の const 変数が代表的な例です。 通常の変数、プロパティ、メソッド呼び出し、 static readonly フィールドはコンパイル時定数ではありません。 開始例では、 >= 18 と <= 24 の両方で、同じ評価された temperature 値をテストします。
同じリレーショナル シンボルは、通常の式またはパターンに表示できます。 次の例では、温度を使って両方の形式を示します。
static void ShowExpressionAndPattern(int temperature, int threshold)
{
bool belowThreshold = temperature < threshold;
bool belowFreezing = temperature is < 0;
string description = temperature switch
{
< 0 => "Freezing",
0 => "Freezing point",
> 0 => "Above freezing"
};
Console.WriteLine(
$"Below threshold: {belowThreshold}; " +
$"below freezing: {belowFreezing}; {description}");
}
temperature < threshold は 関係式です。 両方のオペランドを評価し、 boolを生成します。 どちらのオペランドにも、非連続式を指定できます。
temperature is < 0では、temperatureはパターン入力式です。 C# はそれを評価し、リレーショナル パターン < 0 結果の値をテストします。 スイッチ アーム < 0 => "Freezing"では、 switch 前の式によって入力が提供されるため、パターンには < 0のみが含まれます。
式は、変数thresholdとtemperatureを比較できます。 リレーショナル パターン オペランドはコンパイル時定数である必要があるため、比較値が変数の場合はリレーショナル式を使用します。 比較値が一定の場合、どちらの形式でも機能します。
右オペランドが定数の場合は、主に読みやすくするために選択します。 多くの場合、関係式は 1 つの直接比較に適合します。 リレーショナルパターンは他のパターンと組み合わせることができ、複数の範囲が switch の結果に対応する場合に自然に適しています。
条件と論理パターンを組み合わせる
論理パターンは、 パターン演算子 and、 or、および notでパターンを結合または否定します。
-
andパターンは、両方の入れ子になったパターンが一致する場合に一致します。 -
orパターンは、入れ子になったパターンのいずれかが一致する場合に一致します。 -
notパターンは、入れ子のパターンが失敗したときに成功します。
最初の例では、 and を使用して範囲を記述し、 or を使用して代替手段を記述します。
not パターンでは、status is not Status.Completeのように値を除外できます。 次のメソッドは両方のフォームを示しているため、構文を学習し、同じテストを表現する方法を比較できます。
static bool IsWeekendPattern(DayOfWeek day) =>
day is DayOfWeek.Saturday or DayOfWeek.Sunday;
static bool IsWeekendImperative(DayOfWeek day) =>
day == DayOfWeek.Saturday || day == DayOfWeek.Sunday;
パターン フォームでは、 orによって結合された 2 つの定数パターンが使用されます。 命令形式では、条件付き OR 演算子 ||で結合された 2 つの等値式が使用されます。 どちらのフォームも、この単一の条件に対して簡潔で明確です。 周囲のコードに最適なフォームを選択します。 パターンは、多くの場合、最初の例のように、 switchのいくつかの関連する選択肢を明確にします。
パターン演算子は、ブール式ではなくパターンを形成します。 and は、パターンの組み合わせ、パターンの代替に or 、パターン否定に not に対応します。 ブール式では、 &&、 ||、および !を使用します。 複数のパターンの代替方法で同じ結果が得られた場合は、 or を選択します。 除外されたパターンを表す場合は not を選択すると、受け入れ可能なすべての値を一覧表示するよりも明確になります。
括弧を使ってパターンをグループ化する
かっこで囲まれたパターンでは、かっこを使用して、入れ子になったパターンのグループ化方法を表示または変更します。 結合性 は、括弧を記述しない場合の暗黙的なグループ化と同様に、演算子がどのパターンオペランドをひとまとまりとして扱うかを決定します。 C# では、次のバインド順序を指定します。
notandor
次のテストでは、優先度 1 から 3 または特別な優先度 9 を受け入れます。
static bool IsAcceptedPriority(int priority) =>
priority is (>= 1 and <= 3) or 9;
コンパイラは、orをandの前にグループ化します。 かっこを使用すると、目的のグループ化が明示的になり、2 つの代替手段 (1 から 3、または 9 の範囲) を簡単に確認できます。 読みやすくするために、パターンが and と orを混在させる場合、または複合パターンに適用 not 場合は常にかっこを使用します。 丸括弧は、not (>= 1 and <= 3) にあるように、既定のグループ化方法を変更することもできます。
入れ子になったパターンのランタイム チェック順序は指定されておらず、パターン演算子は、短絡ブール型の規則ではなく、パターンマッチング規則に従います。 結果がチェック順序に依存しないように、入れ子になったパターンを記述します。
別の条件に対して when ガードを使用する
論理パターンは、入れ子になったパターンが入力値自体を記述する場合に最適です。
when ガードは、case ラベルまたはスイッチ アームの追加のブール条件です。 決定がパターン入力とは別の情報にも依存する場合は、ガードを使用します。
次の警告は、温度と個別の isOutdoors 値によって異なります。
static string GetHeatWarning(int temperature, bool isOutdoors) =>
temperature switch
{
> 35 when isOutdoors => "High heat outdoors",
> 35 => "High heat",
_ => "No heat warning"
};
リレーショナル パターン > 35 では、 temperature 入力について説明します。 ガード when isOutdoors は別の値をチェックします。 条件にメソッド呼び出しが必要な場合や、パターン構文が明確に表現されないブール式が必要な場合にも、ガードを使用することをお勧めします。
リレーショナル パターンと論理パターンは、入力の許可された図形または値を、特に複数のスイッチ アーム間で見やすくする場合に使用します。 直接条件がより単純に指定されている場合は、通常のブール式を使用します。 切り替えの選択が別の値に依存する場合、またはブール式として表現される条件に応じて、 when ガードを使用します。
こちらも参照ください
.NET