switch 式
docs.microsoft.com
x switch { ... };
- C# 8.0 以降で使用できる。
- switch 文よりも簡潔に書ける。case・break 不要。
- 判定機能も従来よりかなり充実してる。おすすめ。
- アンダーバー"_" が default と同じ。
- 複数行の処理を行う場合、使用できない。
簡潔に記述できる。
enum SampleEnum
{
Type1,
Type2,
Type3,
}
var input = SampleEnum.Type1;
var result = input switch
{
SampleEnum.Type1 => "タイプ1",
SampleEnum.Type2 => "タイプ2",
SampleEnum.Type3 => "タイプ3",
_ => throw new ArgumentException(input.ToString()),
};
Debug.WriteLine(result);
switch 文だと、短く書きたくてもこれぐらい。ローカル関数などが必要。
var input = SampleEnum.Type1;
var result = GetType(input);
Debug.WriteLine(result);
string GetType(SampleEnum type)
{
switch (type)
{
case SampleEnum.Type1: return "タイプ1";
case SampleEnum.Type2: return "タイプ2";
case SampleEnum.Type3: return "タイプ3";
default: throw new ArgumentException(type.ToString());
}
}
switch 式は、一行の場合に使用できる。
var input = SampleEnum.Type1;
var result = input switch
{
SampleEnum.Type1 =>
{
var dummy = 0;
return "タイプ1";
},
SampleEnum.Type2 => "タイプ1",
SampleEnum.Type3 => "タイプ1",
_ => throw new ArgumentException(input.ToString()),
};
{ } 判定
- null 以外のデフォルト処理を定義できる。
- null は アンダーバー (_) で処理される。
void Sample(SampleEnum? input)
{
var result = input switch
{
SampleEnum.Type1 => "タイプ1",
{ } => "タイプ2 or タイプ3",
_ => "null",
};
Debug.WriteLine(result);
}
Sample(SampleEnum.Type1);
Sample(SampleEnum.Type2);
Sample(null);
比較演算判定
var input = 10;
var result = input switch
{
0 => "0です",
> 0 => "正の数",
< 0 => "負の数",
};
Debug.WriteLine(result);
var result = input switch
{
0 => "0です",
1 => "1です",
2 => "2です",
10 => "10です",
_ => throw new ArgumentException(input.ToString()),
};
Debug.WriteLine(result);
プロパティ判定
- プロパティを部分的に比較判定できる。
- 複数のプロパティで判定することもできる。
以下のクラスを使用する。
public class SampleClass1
{
public int Property1 { get; set; }
public string Property2 { get; set; }
public bool Property3 { get; set; }
}
プロパティを自由に比較できる。これスゴイ。
public void Sample(SampleClass1 value)
{
var result = value switch
{
{ Property1: 1, Property2 : "Test", Property3: true } => $"(^^)/",
{ Property1: 1 } => $"1です",
{ Property2: "Test" } => $"Testです",
{ Property3: true } => $"Trueです",
_ => throw new ArgumentException(value.ToString()),
};
Debug.WriteLine(result);
}
Sample(new SampleClass1() { Property1 = 1 });
Sample(new SampleClass1() { Property2 = "Test" });
Sample(new SampleClass1() { Property3 = true });
Sample(new SampleClass1() { Property1 = 1, Property2 = "Test", Property3 = true });
プロパティ判定+比較演算(when)
かなり自由に書ける。
public void Sample(SampleClass1 value)
{
var result = value switch
{
{ Property1: var x } when x > 0 => $"{x}:0より大きいです",
{ Property2: var x } when (x?.Length ?? 0) > 3 => $"{x}:3文字以上です",
{ Property3: var x } when x => $"{x} です",
_ => throw new ArgumentException(value.ToString()),
};
Debug.WriteLine(result);
}
Sample(new SampleClass1() { Property1 = 1 });
Sample(new SampleClass1() { Property2 = "Test" });
Sample(new SampleClass1() { Property3 = true });
タイプ判定
- switch 文でも判定できたが、switch 式でより簡潔に判定できる。
以下のクラスを使用する。
public class SampleClass1
{
public int Property1 { get; set; }
}
public class SampleClass2
{
public string Property2 { get; set; }
}
public class SampleClass3
{
public bool Property3 { get; set; }
}
public void Sample<T>(T value) where T : class
{
var result = value switch
{
SampleClass1 x => $"{x.GetType().Name}:{x.Property1}",
SampleClass2 x => $"{x.GetType().Name}:{x.Property2}",
SampleClass3 x => $"{x.GetType().Name}:{x.Property3}",
_ => throw new ArgumentException(typeof(T).Name),
};
Debug.WriteLine(result);
}
Sample(new SampleClass1() { Property1 = 10 });
Sample(new SampleClass2() { Property2 = "Test" });
Sample(new SampleClass3() { Property3 = true });
以上