概要
- C# 15 で待望の union型 が正式に導入
- 複数型を安全に扱えるデータ構造として Result<> や Option<> の実装例を紹介
- unionキーワード とその利用方法、実際のコード例を解説
- .NET 11 での利用準備やIDEサポート状況に言及
- カスタムUnion型 の実装やパフォーマンス上の注意点も説明
C# 15のUnion型とは何か
- union型 は、複数の異なる型を一つの型として安全に扱えるデータ構造
- F#、TypeScript、Rustなど多くの関数型言語で一般的な機能
- 例として Result<TSuccess, TError> や Option<T> などがあり、成功・失敗や値の有無を明示的に表現可能
- C# 15以前は、基底クラスの継承やobject型の利用、タグ値管理など煩雑な実装が必要だった
- unionキーワード により、型安全かつ簡潔な記述が可能となった
C# 15でのUnion型の利用方法
- unionキーワード で複数の型をまとめて定義可能
- 例:
public union SupportedOS(Windows, Linux, MacOS);
- 例:
- インスタンス生成は明示的にnewを使うか、暗黙的な型変換が利用可能
- 例:
SupportedOS os = new MacOS("Tahoe", 25);
- 例:
- IUnionインターフェース を自動実装し、格納値へは
.Valueプロパティでアクセス - switch式 で型ごとの分岐処理が簡単に記述可能
- すべての型ケースを網羅しない場合、コンパイル時に警告表示
- null許容型を含む場合は、switch式でnullケースも必須
Union型の実装例
- Result<T>型 の例:
public union Result<T>(T, Exception); - Option<T>型 の例:
public record class None;public union Option<T>(None, T);
- これにより、従来のカスタム実装よりも簡潔で型安全なコードが実現
.NET 11でUnion型を使うための準備
- .NET 11 preview 2以上 のSDKインストールが必要
- プロジェクトファイルに
<LangVersion>preview</LangVersion>を追加- 例:
<LangVersion>preview</LangVersion><TargetFrameworks>net11.0;net8.0;net48</TargetFrameworks>
- 例:
- .NET 11未満やpreview 2/3利用時は、 UnionAttribute や IUnion インターフェースの自前実装が必要
- IDEサポートは Visual Studio Preview や VS Code C# DevKit Insiders で初期対応
- JetBrains Rider のサポートは今後予定
Union型の内部実装について
- [Union]属性 付きのstructとして自動生成され、IUnionインターフェースを実装
- 各ケース型ごとにコンストラクタが生成され、値はobject?型のValueプロパティに格納
- 暗黙的な型変換は、[Union]属性により実現
- [Union]属性を外すと、型変換やswitch式での分岐が利用不可
カスタムUnion型実装とパフォーマンス注意点
- 既存の OneOf や Sasa などのカスタムUnion型も、IUnion実装と[Union]属性付与で言語機能の恩恵を受けられる
- 標準Union型は内部的にobjectとして値を保持するため、struct型の値は ボックス化 されヒープ領域に格納される点に注意
- 例:
public union IntOrBool(int, bool);ではintやboolもobject型として格納
- 例:
- パフォーマンス重視の場合は、独自実装やボックス化回避の工夫が必要
まとめ
- C# 15のunion型 は、複数型を安全に扱うための強力な新機能
- 型安全・簡潔な記述・switch式での分岐が大きなメリット
- 実装やパフォーマンス要件に応じて、標準・カスタムの使い分けが重要