-- Views
August 29, 26
スライド概要
C# 15 の新機能の紹介です。
実際にコードを書いて動かしてみた結果を共有しています。
また、実際に動かす際に気になる基本仕様より深いことも実際のコードと動作で確認しています。
Union types
ユニオン型
Closed hierarchies
クローズド継承
Collection expression arguments
コンストラクタ引数付きコレクション式
Extension indexers
新形式の拡張メソッドでのインデクサ拡張
Labeled break and continue
ラベルへの break / continue
mishizaki
C# 15 にそなえよう。 C# 15 にそなえよう。 石崎 充良 1 / 26
自己紹介 石崎 充良 ( @mishi_cs ) C# Tokyo コミュニティ管理メンバー GitHub: https://github.com/m-ishizaki blog: https://rksoftware.hatenablog.com/ 2 / 26
C# 15 にそなえよう。 そろそろ、.NET Conf の日程も発表され、.NET 11 の GA も近づいてき ました。そうなると、何が起こるでしょう? そう、C# 15 の GA の季節です。 というわけで、C# 15 を復習してみます。 3 / 26
.NET Blog 今回 C# 15 を自分で動かして理解し、気になるところは動作 確認をしてみました。 色々独自にやってみましたが、機能の基本ということであれ ば、.NET Blog の次の記事がまとまっているので、ぜひ参照し てください。 https://devblogs.microsoft.com/dotnet/explore-csharp-15/ 4 / 26
Union types 5 / 26
ユニオン型 「これらの型のうちのどれかが入る変数」というものが作れます。 型定義 6 / 26
ユニオン型 Ku 型の変数には、Chiyoda 型または Taito 型を代入できます。 ちなみに、値を持たない Ku 型の変数も可能です (コード例の ku01 のように)。 Chiyoda 型でも Taito 型でもない型は代入できず、構文エラーです。 7 / 26
ユニオン型 使用例 使うときはパターンマッチングで使うのが基本になりそうです。 特に、取り得る型が確定しているので、静的にパターンの不足をチェックしてくれる のがうれしいです。 次の例では Taito がないので警告がでます。 網羅されると、警告がなくなります。 8 / 26
ユニオン型 キャストの仕方 Union 型は代入した値の型にキャスト できません。 Ku 型に Chiyoda 型を代入できますが、キャストで Ku 型を Chiyoda 型にすることは できません。 代入した値は Ku 型の Value プロパティに居るので、Value プロパティから取り出す ことができます。取り出しものはキャストできます。 9 / 26
ユニオン型 代入と Value プロパティ Ku 型に Chiyoda 型を代入するソースコードを書けるが、実体としては Ku 型 の Value プロパティに Chiyoda 型が入っています。 Ku 型の Type は Ku で Ku 型の Value プロパティの中身の型が Chiyoda であること が確認できます。 10 / 26
ユニオン型 パターンマッチングの場合のみ、Ku 型のみでなく、Value プロパティの中身とマッチ するかも見てくれています。 Union 型は ValueType かつ Ku 型は Chiyoda 型ではないので次のコードは静的にエ ラーです。 11 / 26
ユニオン型 Value は不変 Value プロパティは get のみのため set はできません。 12 / 26
ユニオン型 Value から値を取り出す Value プロパティから値を取り出して処理するコードは、せっかくの Union 型の利点 をつぶしてしまいます。 Ku 型の変数へのパターンマッチングでは、あり得ない型 (次の例ではあり得ない Attribute 型) とマッチしようとしてエラーにしてくれるが、 Value から取り出してしま うと、エラーにしてはくれません。 二つ目のこの例はエラーにしてくれない。うれしくない。 13 / 26
Closed hierarchies 14 / 26
クローズド継承 同一アセンブリ内でのみ継承できる型をつくれます。 型定義のコード クラスライブラリで次のように定義したとします。 closed キーワードが今回のキモです。 Ku 型を継承して、Chiyoda 型、Taito 型を定義 できています。 また、アセンブリ外へ公開しない internal クラスが継承することもできます。 15 / 26
クローズド継承 別アセンブリでの参照 先のクラスライブラリを別のプロジェクトで参照してみます。 次のように、Ku 型が見える使える状態です。 しかし見えるのに継承ができません。 16 / 26
クローズド継承 網羅もされない closed クラスが定義されたアセンブリ外で継承できないので、値の型のパターンも限 定されますことになり、Union 型のような網羅チェックも期待してしまうかもしれませ ん。 しかし、残念ながらできません。Union 型の switch 式のように型の網羅は静的に警告 してもらえません。 そもそも Ku 型は Bunkyo 型の値である可能性があるが、このアセンブリでは Bunkyo 型を扱えない 17 / 26
Collection expression arguments 18 / 26
コンストラクタ引数付きコレクション式 コレクション式でコレクションを作成する場合に、以前はコレクション型のコンスト ラクタ引数を指定できなかったが、with() でコンストラクタ引数を指定できるようにな りました。 次の例ではキャパシティを 256 を指定して初期化しています。 独自型で確認してみる コンストラクタ引数のある型を作って確認してみましょう。 次のように引数のあるコンストラクタと、引数のないコンストラクタを持つクラスを 作ってみました。 19 / 26
コンストラクタ引数付きコレクション式 一つ目は引数のあるコンストラスタが使用される例です。 二つ目は引数のないコンストラスタが使用される例です。 20 / 26
Extension indexers 21 / 26
新形式の拡張メソッドでのインデクサ拡張 新形式の拡張メソッドでのインデクサが定義できるようになりました。 次のように拡張インデクサを定義してみます。 使用してみます。本来インデクサをもたない Object 型でインデクサが使えました。 22 / 26
Labeled break and continue 23 / 26
ラベルへの break / continue ラベルを使って多段のループを狙った階層まで一気に break や continue できます。 飼 いならされた goto です。 コード例 (Break) 次の例は、break でいくつかのループを階層を飛び越えて break しています。 ・count が 1 の場合は break しないので 3 層目のループがもう一度回っています。 ・count が 2 の場合は、ラベル「la02」のループがブレイクするので 1 層目のループに飛んでいます。 ・count が 3 の場合は、ラベル「la01」のループがブレイクするので 1 層目のループから抜けループが終了 します。 24 / 26
ラベルへの break / continue コード例 (continue) 次の例は、continue でもいくつかのループを階層を飛び越えて continue しています。 ・count が 1 の場合は break も continue もしないので 3 層目のループがもう一度回っています。 ・count が 2 の場合は 2 層目 continue なので 2 層目のループがもう一度回っています。 ・count が 3 の場合は、ラベル「lb01」のループがブレイクするので 1 層目のループから抜け ループが終了します。 25 / 26
ラベルへの break / continue 飼いならされた goto のように自由奔放でなく、飼いならされているので、階層の中のでの break と continue しかできません。(うれしい) 次の例はエラーになります。(うれしい) 26 / 26
そなえよう 27 / 26
そなえよう C# 15、本当にいいものですね。 しっかり使用する準備を整え、.NET 11 の GA に備えましょう。 28 / 26
今回の内容のブログ記事 https://rksoftware.hatenablog.com/entry/2026/08/28/190000 29 / 26
ありがとうございました 石崎 充良 30 / 26