nullチェックとデフォルト値設定の簡略化
C#でオブジェクトのプロパティにアクセスする際、そのオブジェクト自体がnullである可能性があります。また、プロパティの値を取得できたとしても、その値がnullであれば、代わりに「未設定」や「不明」といったデフォルト値を使用したいケースが多々あります。
これを従来のif文で記述すると、ネストが深くなり、コードが冗長になりがちです。
C#では、**null条件演算子(?.)とnull合体演算子(??)**を同時に使用することで、この一連のロジックを非常に簡潔な1行のコードで表現できます。
この記事では、これら2つの演算子を組み合わせた実用的なパターン(イディオム)について解説します。
組み合わせの基本パターン
このパターンは、以下の順序で評価されます。
obj?.Property: まず、objがnullでないかチェックします。objがnullなら、この時点で評価を打ち切り、nullを返します。objが存在すれば、Propertyの値を取得します(その値自体がnullの可能性もあります)。
?? "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(ぬるぽ)の発生を確実に防ぎます。targetEmployeeがnullの状態で.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が混入しやすいデータを扱う際には、積極的に活用すべき構文です。
