Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

?? (Null-Coalescing Operator) ใน C# คืออะไร

Null-Coalescing Operator (??)

คืนค่า Left Operand ถ้าไม่ใช่ Null มิฉะนั้นคืนค่า Right Operand


result = left ?? right;
// เทียบเท่า:
result = (left != null) ? left : right;

คุณสมบัติ

  • Short-circuit: ถ้า Left ไม่ Null → ไม่ Evaluate Right
  • ทำงานกับ Nullable Value Types (int?, DateTime?) และ Reference Types
  • Right Operand ต้อง Implicitly Convertible เป็น Type ของ Left
  • Associative: a ?? b ?? c = (a ?? b) ?? c (คืนค่าแรกที่ไม่ Null)

ตัวอย่างพื้นฐาน


using System;

class Program
{
    static void Main()
    {
        // Nullable Value Type
        int? value1 = null;
        int value2 = value1 ?? 99; // 99
        Console.WriteLine($"Value2: {value2}");
        
        // Reference Type
        string testString = "Null Coalescing";
        string result = testString ?? "Original is null";
        Console.WriteLine($"Result: {result}"); // Null Coalescing
        
        // Chain
        string? s1 = null;
        string? s2 = null;
        string s3 = "Third";
        string result2 = s1 ?? s2 ?? s3 ?? "Default";
        Console.WriteLine(result2); // Third
        
        Console.ReadLine();
    }
}

Output

Value2: 99
Result: Null Coalescing
Third

Null-Coalescing Assignment (??=) - C# 8.0+

Assign เฉพาะตอน Left เป็น Null


string? name = null;
name ??= "Default Name"; // Assign เฉพาะตอน null
Console.WriteLine(name); // Default Name

name ??= "Another"; // ไม่ Assign เพราะ name ไม่ null แล้ว
Console.WriteLine(name); // Default Name

Use Cases จริง

1. Default Value สำหรับ Nullable


// แทน
string displayName = user.Name != null ? user.Name : "Anonymous";

// ใช้
string displayName = user.Name ?? "Anonymous";

2. Lazy Initialization


private List<string> _cache;
public List<string> Cache => _cache ??= new List<string>();

3. Fallback Chain


var config = userConfig ?? systemConfig ?? defaultConfig ?? throw new InvalidOperationException("No config");

4. กับ Nullable Reference Types (C# 8+)


#nullable enable
string? maybeNull = GetString();
string notNull = maybeNull ?? "Fallback"; // notNull เป็น string (Non-nullable)
#nullable restore

?? vs ?: (Ternary) vs ?. (Null-Conditional)

OperatorNameใช้เมื่อไหร่
??Null-CoalescingDefault Value เมื่อ Null
?:Ternary/ConditionalCondition ใดๆ (ไม่ใช่แค่ Null)
?.Null-ConditionalAccess Member เมื่อ Object ไม่ Null
??=Null-Coalescing AssignmentAssign เมื่อ Null (Lazy Init)

ร่วมกันใช้ได้


// Safe Navigation + Default
string name = person?.Address?.City ?? "Unknown City";

// Lazy Init + Thread Safety (Simple)
private volatile List<string> _items;
public List<string> Items => _items ??= new List<string>();

ข้อควรระวัง

  • Left Operand ต้องเป็น Nullable Type (Value Type ต้องเป็น T?)
  • Reference Type ใช้ได้เลย (Nullable By Default)
  • ไม่ทำงานกับ Non-Nullable Value Type (int ต้องเป็น int?)