C#の新たなる進化──プライマリコンストラクタとコレクション式などバージョン12の注目機能を紹介!
【C#で知っておくべき新機能】最新バージョンを徹底解説! 第4回
ダウンロード サンプルファイル (5.5 KB)
第4回では、クラスでも利用可能になったプライマリコンストラクタ、より簡潔な記述が可能になったコレクション式、左辺値参照のみを読み出し専用にするref readonly修飾子、引数のデフォルト値が設定可能になったラムダ式を紹介します。
はじめに
C#は、この11月に.NET 8のリリースとともにバージョン12となりました。C#は、.NETの標準プログラミング言語として絶え間ない進化を続けており、このバージョン12にも便利で使い勝手のよい機能が多数実装されました。本連載では、このC#の最新バージョンにフォーカスし、その新機能を紹介していきます。また、最新バージョン以前の機能にも関連の深いものについて言及することで、新機能を線として理解できることも意識します。
| 機能 | 概要 |
|---|---|
| プライマリコンストラクタ | record型のみでサポートされていたプライマリコンストラクタがクラスでも利用可能に |
| コレクション式 | 配列やリストなどのコレクションをより簡潔な書式で記述可能に |
| ref readonlyパラメータ | 左辺値を読み出し専用で関数に渡す場合の意図を明確に |
| デフォルトのラムダ式パラメータ | ラムダ式のパラメータに既定値を定義できるように |
| 任意の型エイリアス | タプル型、配列型、ポインタ型などにも別名を設定可能に |
| インライン配列 | struct型の固定長配列の利用が可能に |
| Experimental属性 | 試験的機能を示す新しい属性を指定可能に |
| インターセプタ | コンパイル時に置き換え可能なメソッドを定義可能に |
対象読者
- C#の最新バージョンの機能を把握したい方
- C#の経験者で、C#に改めて入門したい方
- プログラミング言語の最新パラダイムに関心のある方
必要な環境
本記事のサンプルコードは、以下の環境で動作を確認しています。
-
macOS Sonoma
- .NET 8 SDK(8.0.101)
サンプルの実行
掲載サンプルは、基本的にプロジェクトのProgram.csファイルに記述されています。簡略化のために、C# 9より使用可能になったトップレベルステートメントの記法を用いています。このため、クラスなどの定義がソースコードの後方に配置されます。また、.NET 8環境でのみ動作しますので、.NET 8環境を用意した上で、プロジェクトフォルダでdotnet runコマンドで実行してください。
C# 9で実装されたプライマリコンストラクタが、クラスと構造体でも利用可能に
C# 12では、レコード型にはすでに実装されていたプライマリコンストラクタ(Primary constructors)が、クラスと構造体でも利用可能になりました。
プライマリコンストラクタとは、よりシンプルに定義できるコンストラクタの一種です。その名(プライマリ=第一の、最優先の)の通り、他にコンストラクタを定義する場合、それらは必ずプライマリコンストラクタを呼び出す必要があります。また、プライマリコンストラクタをクラス内に複数定義することはできません。
C# 9で実装されたレコード型において、このプライマリコンストラクタがすでに導入されていました。機能の差異はありますが、レコード型と同様にクラスと構造体においてもプライマリコンストラクタが利用できるようになりました。
プライマリコンストラクタの定義例を示す前に、従来のコンストラクタ定義をリストに示します。特に解説の必要なコードではありません。
class ClassNoPrimaryConstructor
{
public int a;
public ClassNoPrimaryConstructor(int _a)
{
a = _a;
}
}
プライマリコンストラクタを使うと、上記は以下のリストとなります。
class ClassUsePrimaryConstructor(int _a) (1)
{
public int a = _a; (2)
}
(1)のように、コンストラクタの引数はクラス名に続けます。そして(2)のようにフィールド定義の初期値に引数を指定します。これで、初期値を伴うコンストラクタの定義ができたことになり、いたって記述がシンプルになります。
なお、プライマリコンストラクタが引数を必要としない場合、クラスはフィールドを全く持たないことも可能になりますが、その場合は「class ClassUsePrimaryConstructorWithNoArgs;」のように中かっこも省いた定義が可能です。
プライマリコンストラクタは、既述の通り最優先で呼び出すべきコンストラクタです。プライマリコンストラクタを定義すると、その他のコンストラクタにおいてプライマリコンストラクタの呼び出しが必須となります。これによって、クラスのフィールドを確実に初期化できます。
class ClassWithConstructor(int _a)
{
public int a = _a;
// 引数なしコンストラクタ
public ClassWithConstructor(): this(0) {} (1)
}
(1)において、引数なしのコンストラクタにおいて、thisによるプライマリコンストラクタの呼び出しが強制されることで、安全にフィールドを0に初期化できます。仮にthisの記述を省くとコンパイルエラーとなります。
レコード型との違い
レコード型におけるプライマリコンストラクタとクラスにおけるそれとは大きな違いがあります。それは、レコード型ではプロパティやEqualsなどのメソッドが自動生成される点です。例えば上記の例をレコード型に置き換えると、以下のリストのようになります。
record RecordUsePrimaryConstructor(int a)
{
// aに相当するプロパティは自動生成される
}
これで、ゲッタ、initアクセサを含むプロパティaが生成されます。クラスの場合は、プライマリコンストラクタの引数にあっても対応するフィールドの定義がない場合、引数は単に使われなくなるだけなので大きな違いです。レコード型はデータ保持が主な目的であり、イミュータブル(変更不可)という性質を持つことから、必要なアクセサやメソッドの実装が容易であるからと考えられます。クラスは基本的にミュータブル(変更可)であり、継承を含めた複雑な実装もあり得ることから、自動生成は無理だということでしょう。
プライマリコンストラクタにより、インスタンス生成をより安全に確実に実行できるようになりました。
この記事は参考になりましたか?
- 【C#で知っておくべき新機能】最新バージョンを徹底解説!連載記事一覧
- この記事の著者
-
WINGSプロジェクト 山内 直(WINGSプロジェクト ヤマウチ ナオ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。出版社を経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
