【C#】null条件演算子(?.)とnull合体演算子(??)の組み合わせ:安全なプロパティアクセスとデフォルト値

目次

nullチェックとデフォルト値設定の簡略化

C#でオブジェクトのプロパティにアクセスする際、そのオブジェクト自体がnullである可能性があります。また、プロパティの値を取得できたとしても、その値がnullであれば、代わりに「未設定」や「不明」といったデフォルト値を使用したいケースが多々あります。

これを従来のif文で記述すると、ネストが深くなり、コードが冗長になりがちです。

C#では、**null条件演算子(?.null合体演算子(??)**を同時に使用することで、この一連のロジックを非常に簡潔な1行のコードで表現できます。

この記事では、これら2つの演算子を組み合わせた実用的なパターン(イディオム)について解説します。


組み合わせの基本パターン

このパターンは、以下の順序で評価されます。

  1. obj?.Property: まず、objnullでないかチェックします。
    • objnullなら、この時点で評価を打ち切り、nullを返します。
    • objが存在すれば、Propertyの値を取得します(その値自体がnullの可能性もあります)。
  2. ?? "Default": 左側の結果(1.の結果)がnullであれば、右側のデフォルト値を採用します。

つまり、「オブジェクトが存在しない場合」または「プロパティの値がnullの場合」の両方をまとめてケアできます。


コード例:社員データの検索と部署名の取得

社員リストから特定の条件で社員を検索し、その社員が所属する部署名を取得するシナリオを考えます。

  • 社員が見つからない(null)可能性がある。
  • 社員は見つかったが、部署が未所属(null)の可能性がある。

この両方のケースにおいて、最終的に "所属なし" という文字列を取得するように実装します。

using System;
using System.Collections.Generic;
using System.Linq;

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public Department? Department { get; set; } // 部署は null の可能性がある
}

public class Department
{
    public string DepartmentName { get; set; } = "";
}

public class NullOperatorsCombination
{
    public static void Main()
    {
        var employees = new List<Employee>
        {
            new Employee 
            { 
                Id = 1, 
                Name = "佐藤 健", 
                Department = new Department { DepartmentName = "営業部" } 
            },
            new Employee 
            { 
                Id = 2, 
                Name = "鈴木 一郎", 
                Department = null // 部署なし
            }
        };

        Console.WriteLine("--- 社員情報の検索 ---");

        // ケース1: 社員も部署も存在する (佐藤)
        PrintDepartmentName(employees, 1);

        // ケース2: 社員はいるが、部署がない (鈴木)
        PrintDepartmentName(employees, 2);

        // ケース3: 社員自体が存在しない (ID: 99)
        PrintDepartmentName(employees, 99);
    }

    private static void PrintDepartmentName(List<Employee> list, int searchId)
    {
        // IDで社員を検索 (見つからない場合は null が返る)
        var targetEmployee = list.FirstOrDefault(e => e.Id == searchId);

        // 【重要】 ?. と ?? の組み合わせ
        // 1. targetEmployee が null なら、?. は即座に null を返す
        // 2. Department が null なら、?. は null を返す
        // 3. DepartmentName までアクセスできれば、その値を返す
        // 4. 上記のいずれかで null になった場合、?? が "所属なし" を返す
        
        string deptName = targetEmployee?.Department?.DepartmentName ?? "所属なし";

        Console.WriteLine($"ID {searchId}: {deptName}");
    }
}

出力結果:

--- 社員情報の検索 ---
ID 1: 営業部
ID 2: 所属なし
ID 99: 所属なし

この記述のメリット

1. 安全性の向上

NullReferenceException(ぬるぽ)の発生を確実に防ぎます。targetEmployeenullの状態で.Departmentにアクセスしようとするリスクを排除できます。

2. 可読性の向上

同じロジックをif文で書くと以下のようになります。

string deptName;
if (targetEmployee != null && targetEmployee.Department != null)
{
    deptName = targetEmployee.Department.DepartmentName;
}
else
{
    deptName = "所属なし";
}

これに比べて var deptName = targetEmployee?.Department?.DepartmentName ?? "所属なし"; は、意図が一目で伝わり、コード行数も大幅に削減されます。


まとめ

?.(null条件演算子)と ??(null合体演算子)の組み合わせは、C#において「オブジェクトの階層を安全に辿り、値が取得できなければデフォルト値を使う」という頻出パターンを処理するための最適解です。

APIレスポンスの解析や、データベースからの値の取得など、nullが混入しやすいデータを扱う際には、積極的に活用すべき構文です。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

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

目次