C# 8.0から使用できるswitch式で、整数の範囲とマッチさせたい場合、破棄パターン+when
句で下記のようになります。
var num = 100;
var rsult = input switch {
_ when 1 <= num && num < 13 => "special",
_ => "",
};
これでも十分ですが、どうせならC# 8.0から導入されたSystem.Range
構造体(1..13
)を使用したいです。
しかし、System.Range
構造体は配列内の範囲を表すことを想定されて設計されているため、特定の値が含まれるかどうかを判定するメソッドがありません。
Enumerable.Range()
メソッドを使えばもう少し綺麗に書けますが、ヒープにオブジェクトが作成されるのが少し嫌なので拡張メソッドを用意します。
拡張メソッド
static class RangeExtention
{
public static bool Contains(this Range range, int value)
{
var start = range.Start.IsFromEnd ? (int.MaxValue - range.Start.Value) : range.Start.Value;
var end = range.End.IsFromEnd ? (int.MaxValue - range.End.Value) : range.End.Value;
if (start > end)
throw new ArgumentOutOfRangeException(nameof(range));
return start <= value && value < end;
}
}
var num = 100;
var rsult = num switch {
_ when (1..13).Contains(num) => "special",
_ => "",
};
注意点
System.Range
構造体を使用するので、制約があります。
- 型は
int
しか使用できない。 - 値の範囲は0以上しか使用できない。(
Enumerable.Range()
メソッドを使えば負値も可能) -
(2..0)
のような、大小関係が逆転している範囲は例外を投げるようにしている。 - 半閉区間しか使用できない。
(System.Range
構造体の想定は半閉区間なのでそれに従っている。)