【C#】null合体割り当て演算子(??=)の使い方:変数がnullの時だけ値を代入する

目次

条件付き代入の簡略化

プログラミングにおいて、「変数がまだ初期化されていない(nullである)場合に限り、初期値やデフォルト値を代入したい」というロジックは頻繁に登場します。

従来、この処理はif文を使用して記述されてきましたが、C# 8.0で導入された「null合体割り当て演算子(??=」を使用することで、より簡潔かつ直感的に記述できるようになりました。

この記事では、??=演算子の基本的な使い方と、従来の方法との違い、そして実用的なメリットについて解説します。


null合体割り当て演算子 (??=) とは

??= 演算子は、左側の変数が null である場合にのみ、右側の値を評価して代入します。左側の変数が null でない場合、右側の値は評価されず、代入も行われません。

構文: 変数 ??= 値;

これは、以下のコードとほぼ同等の意味を持ちます。

if (変数 is null)
{
    変数 = 値;
}

コード例1:基本的なデフォルト値の設定

ユーザーからのコメント入力処理を例にします。コメントが未入力(null)の場合に、自動的にデフォルトのメッセージを設定するコードです。

using System;

public class DefaultValueExample
{
    public static void Main()
    {
        // ケース1: コメントが null の場合
        string? userComment = null;

        // userComment が null なので、"No comment provided." が代入される
        userComment ??= "No comment provided.";

        Console.WriteLine($"コメント1: {userComment}");

        // ケース2: コメントが既に存在する場合
        string? existingComment = "Great post!";

        // existingComment は null ではないため、右辺は評価されず、代入も行われない
        existingComment ??= "No comment provided.";

        Console.WriteLine($"コメント2: {existingComment}");
    }
}

出力結果:

コメント1: No comment provided.
コメント2: Great post!

従来の方法 (if文) との比較

??= 演算子が導入される前は、同様の処理を行うために if 文によるチェックが必要でした。

従来の書き方

string? categoryName = null;

if (categoryName == null)
{
    categoryName = "Uncategorized";
}

??= を使った書き方

string? categoryName = null;

categoryName ??= "Uncategorized";

??= を使用することで、コードの行数が削減されるだけでなく、「nullの場合に初期化する」という意図がより明確になります。


コード例2:リストの遅延初期化(Lazy Initialization)

??= 演算子の真価が発揮されるのは、リストやオブジェクトの「遅延初期化」を行う場面です。

オブジェクトを最初から生成するのではなく、「必要になった瞬間(変数がまだnullの時)」に生成することで、メモリ使用量を節約し、パフォーマンスを向上させるパターンです。

using System;
using System.Collections.Generic;

public class SearchQuery
{
    // 初期状態は null (メモリを確保しない)
    public List<string>? SearchTags { get; private set; }

    public void AddTag(string tag)
    {
        // SearchTags が null の場合のみ、新しい List<string> を生成して代入
        // すでに生成されていれば、そのまま使用する
        SearchTags ??= new List<string>();

        SearchTags.Add(tag);
        Console.WriteLine($"タグを追加しました: {tag}");
    }
}

public class Program
{
    public static void Main()
    {
        var query = new SearchQuery();

        // まだ SearchTags は null
        Console.WriteLine($"初期状態: {query.SearchTags is null}");

        // 初めてタグを追加 (ここで List が生成される)
        query.AddTag("C#");
        
        // 2回目は既存の List が使われる (再生成されない)
        query.AddTag("Programming");

        Console.WriteLine($"タグの数: {query.SearchTags?.Count}");
    }
}

出力結果:

初期状態: True
タグを追加しました: C#
タグを追加しました: Programming
タグの数: 2

この例では、SearchTags プロパティは最初は null です。AddTag メソッドが呼ばれたときに初めて new List<string>() が実行されます。??= を使うことで、このロジックを1行で記述できています。


まとめ

null合体割り当て演算子(??=)は、変数が null のときだけ値を代入するための演算子です。

  • 簡潔性: if (x == null) x = y;x ??= y; と短く記述できます。
  • 効率性: 左辺が null でない場合、右辺の処理(オブジェクト生成など)は実行されないため、パフォーマンス上の無駄がありません。
  • 用途: デフォルト値の設定や、コレクションの遅延初期化に最適です。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次