0Pricing
C# Academy · レッスン

Null条件演算子とNull合体演算子

?., ?[], ??、??=を組み合わせて、冗長なnullチェックなしで簡潔なnull安全コードを記述します。

「Null条件演算子とNull合体演算子」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。

Null 安全コードのパターン

C# には、null 値を簡潔に扱うための 3 つの専用演算子があります。null 条件演算子(?.、?[])、null 合体演算子(??)、null 合体代入演算子(??=)です。これらを組み合わせることで、冗長な null チェックの定型コードのほとんどをなくせます。

Null 条件演算子:?.

?. は、左辺が null の場合に例外をスローせず、処理を短絡して null を返します。結果の型は null 許容型になります。

User? user = GetUser(id);

// Without ?.:
string? name = null;
if (user != null) name = user.Name;

// With ?.:
string? name2 = user?.Name;

// Chained:
string? city = user?.Address?.City;

// Method call:
string? upper = user?.Name?.ToUpper();

インデックスアクセサーを使った Null 条件:?[]

?[] は null 条件インデックス演算子です。コレクション自体が null になる可能性がある場合でも、配列やコレクションの要素に安全にアクセスできます。

List<string>? tags = product?.Tags;

// Safe index access
string? firstTag = tags?[0];

// Null-conditional LINQ
int? count = tags?.Count;
bool? hasItems = tags?.Any();

// With methods:
string? joined = tags?.FirstOrDefault()?.ToUpper();

Null 合体演算子:??

?? は、左オペランドが null でなければ左オペランドを返し、null であれば右オペランド(フォールバック値)を返します。x != null ? x : fallback を簡潔に置き換えられます。

string? name = GetName();

// Without ??:
string display = name != null ? name : "Anonymous";

// With ??:
string display2 = name ?? "Anonymous";

// Chaining ?? for multiple fallbacks:
string result = primary ?? secondary ?? tertiary ?? "Default";

// Combining with ?.
string city = user?.Address?.City ?? "Unknown City";

null 合体代入: ??=

??=は、変数が現在nullの場合にのみ、右辺の値をその変数に代入します。遅延初期化のパターンに最適です。

// Lazy initialization
private List<string>? _cache;

public List<string> GetCache()
{
    _cache ??= new List<string>(); // only assigns if null
    return _cache;
}

// Equivalent to:
// if (_cache is null) _cache = new List<string>();

// In-place:
string? name = null;
name ??= "Default";
Console.WriteLine(name); // "Default"

イベントで ?. を使う

null 条件演算子は、イベントを呼び出すための標準的なスレッドセーフの方法です。null チェックと呼び出しを別々に行う場合に発生する競合状態を回避できます。

public event EventHandler<DataEventArgs>? DataReceived;

// Thread-safe event invocation:
DataReceived?.Invoke(this, new DataEventArgs(data));

// This is equivalent to:
var handler = DataReceived;
if (handler != null) handler(this, new DataEventArgs(data));
// (local copy avoids race condition between check and invoke)

複雑なチェーンの例

演算子を組み合わせることで、深くネストされたオブジェクトグラフを、わかりやすく安全に null チェーンでたどれます。

var order = GetOrder(id);

// Deeply nested with fallbacks:
string countryCode = order
    ?.Customer
    ?.ShippingAddress
    ?.Country
    ?.Code
    ?? "US";

// Collection safe access:
decimal firstLineTotal = order
    ?.Lines
    ?.FirstOrDefault()
    ?.Total
    ?? 0m;

// Method chain:
string? trackingUpper = order?.TrackingNumber?.ToUpper().Trim();

LINQ での null 条件演算子

null 条件演算子は LINQ とシームレスに連携し、null の可能性があるコレクションやプロパティを安全にクエリできます。

List<Order>? orders = customer?.Orders;

// Safe LINQ on a nullable collection:
var totalRevenue = orders?.Sum(o => o.Total) ?? 0m;
var pendingCount = orders?.Count(o => o.Status == OrderStatus.Pending) ?? 0;
var latest       = orders?.MaxBy(o => o.PlacedAt)?.Id;

ThrowIfNull による null ガード

null であってはならないパラメーターには、メソッドの入り口で簡潔かつ説明的な検証を行える ArgumentNullException.ThrowIfNull()(.NET 6 以降)を使用します。

public void ProcessOrder(Order order, Customer customer)
{
    ArgumentNullException.ThrowIfNull(order);
    ArgumentNullException.ThrowIfNull(customer);

    // From this point, compiler knows both are non-null
    Console.WriteLine(order.Id);
    Console.WriteLine(customer.Name);
}

// .NET 7+: ArgumentException.ThrowIfNullOrEmpty
void Save(string name)
{
    ArgumentException.ThrowIfNullOrWhiteSpace(name);
    // name is guaranteed non-empty
}

switch での null ではないパターン

is not null と is { } によるパターンマッチングを使うと、特に switch 式で null チェックをすっきり記述できます。

string Describe(object? obj) => obj switch
{
    null                          => "nothing",
    string s when s.Length == 0  => "empty string",
    string s                      => $"string: {s}",
    int i                         => $"integer: {i}",
    { }                           => $"object: {obj.GetType().Name}"
};

// is not null in if statements:
if (order is not null && order.Customer is { Name: var name })
    Console.WriteLine(name);

クイックチェック

user?.Name ?? "Anonymous" という式は、user が null の場合に何を返しますか。

まとめ: null 条件演算子と null 合体演算子

重要なポイント:

  • ?.: 安全なメンバーアクセス。null のレシーバーに対して例外をスローせず、null を返します
  • ?[]: null の可能性があるコレクションへの安全なインデックスアクセス
  • ??: 左オペランドが null の場合のフォールバック値
  • ??=: null の場合にのみ代入。遅延初期化に最適です
  • チェーンして使用: a?.B?.C ?? defaultVal で深い階層を null 安全にたどれます
  • パラメーターの検証ガードには ArgumentNullException.ThrowIfNull() を使用します

よくある質問

「Null条件演算子とNull合体演算子」レッスンは無料ですか?

はい。「Null条件演算子とNull合体演算子」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。

「Null条件演算子とNull合体演算子」で何を学びますか?

?., ?[], ??、??=を組み合わせて、冗長なnullチェックなしで簡潔なnull安全コードを記述します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「Null条件演算子とNull合体演算子」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. NRTの有効化と理解
  2. アノテーション:?、!、MaybeNullとNotNull
  3. Null条件演算子とNull合体演算子
  4. コードベースのNRTへの移行
← C# Academyに戻る