この章のテーマ §
C#のパターンについて学びます。C#のパターンは、なくてもソースコードは書けますが、あると表現力がアップする頼もしい味方です。
前提知識 §
Console.WriteLineメソッド, 文字列の基礎, 変数の基礎, 配列の基礎, 条件演算子, int型, string型, DateTime型, for文, foreach文, プロパティ, フィールド
解説 §
C#には多くの種類のパターンがあります。いずれも「無くてもプログラムは書けるが、あるとソースコードが簡潔になる」という特徴を持ちます。
サンプルソースを順を追って説明します。
宣言パターンと型パターンの例は、"item is string message"という式で、itemの型がstring型か調べると同時に、変数messageを宣言し、もし条件を満たしていればitemの値を指定の型に変えてmessageに代入します。
var パターンは、それに似ていますが、型を変換せずただ単に代入します。長い式で途中経過を保管する際に便利です。
リレーショナル パターンは、switch式で特定の値ではなく、大小の指定を含めることを可能とします。
論理パターン1は、特定の値がnullではないことを調べる際、"is not null"という表記を可能にします。
論理パターン2は、switch式の条件にandやorのキーワードを付けることで複数条件を列挙できることを示します。
プロパティ パターンは、オブジェクトが持つプロパティやフィールド値が指定の通りかを調べます。
かっこで囲まれたパターンは、括弧で囲むことで評価の順番を変更できることを意味します。 かっこで囲まれた範囲が先に評価されます。
他にもC#にはパターンがあり、バージョンアップするごとに増えています。興味のある人は他のどんなパターンがあるか調べてみましょう。
罠の数々 §
- パターンはいずれも、基本機能をもっと短く書けるようにしたものなので、無理に覚える必要はない
- しかし、ネットなどの各種サンプルソースを見るときにそこにひょいと出てくることがあるので、知っておいて損は無い
- C#に慣れたら、パターンを使ってソースコードをより短くエレガントに書けないがチャレンジしてみよう
参考リンク §
パターン (C# リファレンス)
サンプルソース: patterns §
// 宣言パターンと型パターン
// string型の場合はToLowerメソッドで小文字にして出力
object?[] array = { "ONE", 2, 3, null };
foreach (var item in array)
{
if (item is string message) Console.WriteLine(message.ToLower());
}
// var パターン
string a = "Hello!";
var x = a is var b;
Console.WriteLine($"a={a}");
Console.WriteLine($"b={b}");
Console.WriteLine($"x={x}");
// リレーショナル パターン
// 値が3ならヒットする
for (int i = 1; i < 6; i++)
{
var r = i switch
{
< 3 => "小さすぎ",
> 3 => "大きすぎ",
3 => "ヒット",
};
Console.WriteLine($"{i}は{r}。");
};
// 論理パターン1
// nullは除外
foreach (var item in array)
{
if (item is not null) Console.WriteLine(item);
}
// 論理パターン2
// 1より大きく4より小さい値だけヒット
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i switch
{
> 1 and < 4 => "ヒット",
_ => "ヒットしない"
});
}
// プロパティ パターン
// 2030年1月だけ捜す
DateTime[] dates =
{
new DateTime(2030,1,2),
new DateTime(2030,2,1),
new DateTime(2031,1,1),
};
foreach (var item in dates)
{
if (item is { Year: 2030, Month: 1 }) Console.WriteLine($"{item}: ヒット");
}
// かっこで囲まれたパターン
// long型の値123Lは32bit整数か? (違う。64bit整数だ)
// intは32bit符号付き整数、uintは32bit符号なし整数。特殊な型を除いて通常はこの2つが32bit整数
object v = 123L;
if (v is not (int or uint)) Console.WriteLine("32bit整数ではない");
実行結果 §
one
a=Hello!
b=Hello!
x=True
1は小さすぎ。
2は小さすぎ。
3はヒット。
4は大きすぎ。
5は大きすぎ。
ONE
2
3
ヒットしない
ヒットしない
ヒット
ヒット
ヒットしない
2030/01/02 0:00:00: ヒット
32bit整数ではない
リポジトリ §
https://github.com/autumn009/CSharpPrimer2
練習問題 §
"item is string message"という式で宣言されたmessageという変数は、あとから別の値を代入して書き換えて良いのだろうか。
- ダメ。書き換えると変数値が想定と違うことになり、プログラムが異常動作する
- ダメ。書き換えは許されていない。書き換えようとするとコンパイラがエラーにする
- 良い。要するに変数宣言を式の中でやっているだけで、結果として産まれるのはただの変数である
[[解答]]