HOWTO · Csharp
C# における typedef の同等機能
C# の using エイリアスで typedef 相当の名前を付ける方法を、C# 12 のタプル別名と通常のジェネリック型別名の例とともに説明します。
このページの内容
C# には typedef キーワードがありません。最も近い機能は using エイリアスです。既存の名前空間や型に、ファイル内で使う別名を付けられます。
エイリアスはコードを読みやすくしますが、実行時に新しい型を作りません。独自の動作や検証を持つ別の型が必要なら、クラス、record、または構造体を定義します。
既存の型に using エイリアスを使う
エイリアスはファイル先頭のほかの using ディレクティブと並べ、完全修飾した型を指定します。これにより、別の using に依存しません。
たとえば、using RouteTable = System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<int>>; は既存の構築済みジェネリック型に名前を付けます。
RouteTable は Dictionary<string, List<int>> の短い表記にすぎません。型安全性や新しい宣言を追加することはなく、通常のエイリアスは宣言したソースファイル内だけで有効です。
using の形式には役割の違いがあります。using System.Text; は名前空間を導入し、using static System.Math; は静的メンバーを導入し、using RouteTable = ...; はエイリアスを作ります。
C# 12 のタプル別名とジェネリック型の別名
C# 12 では、タプルのように以前は名前を付けられなかった型も using エイリアスの対象にできます。名前付き型や構築済みジェネリック型の通常の別名は、C# 12 より前からサポートされています。次の例は両方の形式を使います。
using RouteTable = System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<int>>;
using Coordinate = (double Latitude, double Longitude);
RouteTable routes = new() { ["home"] = [1, 2] };
Coordinate point = (52.37, 4.90);
System.Console.WriteLine($"{routes["home"].Count}:{point.Latitude:F2}");
2:52.37
この成功例は、ネットワークを無効にした分離済みの .NET 10.0.401 環境で復元・ビルドしました。プロジェクトをコンテナーの一時領域へコピーし、--ignore-failed-sources で復元して実行しました。fixture とイメージは変更していません。
C# 11 以前を対象にする場合、任意の型形式へのエイリアスが使えるとは限りません。ツールチェーンを更新するか、完全な型名を記述してください。名前付き型のエイリアスは C# 12 より前から利用できます。
エイリアスでできないこと
エイリアスは typedef のような独立した型ではありません。RouteTable と完全な Dictionary 型はコンパイル時に交換可能です。値を別の値と誤って渡せないようにするには、record や構造体などのドメイン型を使います。
タプルのエイリアスもタプルの形に読みやすい名前を付けるだけで、名前付きクラスにはなりません。要素名はアクセスと文書化に役立ちますが、独立した型の同一性は提供しません。
null 許容参照型のエイリアスは境界になる
拡張されたエイリアス構文にも制限があります。トップレベルの null 許容参照型はエイリアスの対象にできません。そのため using MaybeName = string?; は意図的に無効です。
コンパイラーは、string? がこの位置で許可された型ではなく null 許容参照アノテーションであるため宣言を拒否します。境界 fixture はコンパイルに失敗することが正しく、実行可能な解決策として扱ってはいけません。
実際の型を定義する場合
名前が独立した概念を表す必要があるなら、クラス、record、または構造体を選びます。不変条件、検証、メソッド、生成制御、等価性、公開 API が必要な場合が該当します。単に長い型のファイル内表記を短くしたい場合はエイリアスを使います。
詳しくは Microsoft の using ディレクティブ、C# 12、using alias の提案を参照してください。
FAQ
- C# は
typedefをサポートしますか。 いいえ。usingエイリアスか実際の型を使います。 - タプルにエイリアスを付けられますか。 C# 12 以降で可能です。
- エイリアスはすべてのファイルで有効ですか。 いいえ、宣言したファイルだけです。
- 新しい型を作りますか。 いいえ、既存の型を参照します。
- なぜ
using MaybeName = string?;は失敗しますか。 トップレベルの null 許容参照型は対象として禁止されているためです。