C#14新機能

C#14 新機能 D01_Null条件付き代入

今回はC# 14で追加された「null条件付きの代入」を扱います。

null条件付き(?を付ける書き方)でnullかどうかをチェックしてから処理する、という書き方自体はこれまでのバージョンでも可能でした。例えばProductクラスが次のように定義されているとします。

public class Product
{
  public int ProductId { get; set; }
  public string ProductName { get; set; }
}

 

このProduct型の変数pがnullかもしれない状況で、次のように書くことは以前のバージョンでも可能でした。

p?.ProductId == 1

C# 13以前:読み込みはできるが書き込みはできない

以下はVisual Studio 2022(C# 13)で確認している内容です。まずタイトルスライドで今回のテーマを確認します。

図1 タイトルスライド「【C#14】Null条件付き代入」

Productクラスを定義し、ProductIdプロパティを用意します。

図2 Productクラスの定義(ProductIdプロパティ)

Product型の変数pをnullで初期化し、if文でp?.ProductId == 1のように読み込みを行う書き方は、C# 13以前でも問題なく書けます。pがnullであれば1と等しくないと判定され、nullでなければProductIdが1かどうかがチェックされる、という流れです。

図3 if (p?.ProductId == 1) と書いた状態(読み込みは可能)

一方で、同じ?を使ってp?.ProductId = 999;のように代入(書き込み)しようとすると、C# 13以前ではエラーになります。pがnullだった場合にnullへ999を代入することになってしまい、意味が通らなくなるためです。このように、これまでは?を付けた変数への代入という書き方自体ができませんでした。

図4 p?.ProductId = 999; はCS0131エラーになる(代入式の左辺には変数、プロパティ、またはインデクサーを指定してください)

C# 14:null条件付き代入が可能に

続いてVisual Studio 2026(C# 14)で同じコードを書いてみます。新規にWindowsフォームアプリのプロジェクトを作成します。

図5 Visual Studio 2026で新規作成したプロジェクト(WinFormsApp2026)

先ほどと同じProductクラスとp?.ProductId == 1の判定に加えて、p?.ProductId = 999;という代入も書いてみます。C# 14ではどちらもエラーにならず、書けるようになっています。

Product p = null;
if (p?.ProductId == 1)
{

}

p?.ProductId = 999;

 

実際に動かして確認します。pはnullの状態なので、p?.ProductId = 999;を通過してもエラーにならず、pはnullのままであることが確認できます。ブレークポイントで停止した状態でp?.ProductIdにカーソルを合わせると、値がnullであることがわかります。

図6 ブレークポイントでp?.ProductId = 999; の直前を確認(p?.ProductId は null)

図7 デバッグ実行で行を通過(0エラーで実行できている)

内部的な動き

null条件付き代入p?.ProductId = 999;は、内部的には次のコードと同じ意味になります。pのnullチェックを行ってから、nullでなければ代入を行う、という処理です。

図8 p?.ProductId = 999; と、それと同じ意味を持つ if (p != null) { p.ProductId = 999; }

p?.ProductId = 999;

// 上記は次のコードと同じ意味
if (p != null)
{
  p.ProductId = 999;
}

 

これまでは「?を付けた変数への代入」という書き方ができませんでしたが、C# 14以降ではこのnull条件付きの代入が可能になりました。

C#14 新機能