null สำหรับ List<T> หมายถึงตัวแปรไม่ได้ชี้ไปที่ออบเจกต์ใดๆ (No object reference) ต่างจาก Empty List ที่เป็นออบเจกต์ที่มีอยู่แต่ไม่มีข้อมูล การเข้าถึง Null List จะโยน NullReferenceException
การสร้าง Null List
List nullList = null; // Explicit null
List uninitialized; // Field ของคลาสจะเป็น null อัตโนมัติ (ไม่ใช่ local variable)
โค้ดตัวอย่างสมบูรณ์
using System;
using System.Collections.Generic;
public class Demo
{
public static void Main()
{
// Null List
List nullList = null;
Console.WriteLine($"nullList == null: {nullList == null}"); // True
// การเข้าถึง Null List จะเกิด Exception
try
{
int count = nullList.Count; // NullReferenceException!
}
catch (NullReferenceException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
// วิธีตรวจสอบอย่างปลอดภัย
Console.WriteLine("\n--- วิธีตรวจสอบ Null อย่างปลอดภัย ---");
// 1. Null check แบบคลาสสิค
if (nullList != null)
{
Console.WriteLine($"Count: {nullList.Count}");
}
else
{
Console.WriteLine("List เป็น null");
}
// 2. Null-conditional operator (?.) - C# 6+
Console.WriteLine($"Count (safe): {nullList?.Count ?? 0}"); // 0
// 3. Pattern Matching - C# 7+
if (nullList is List list)
{
Console.WriteLine($"ไม่เป็น null, Count = {list.Count}");
}
else
{
Console.WriteLine("เป็น null");
}
// 4. การกำหนดค่าเริ่มต้น (Coalesce)
List safeList = nullList ?? new List();
safeList.Add("Safe!");
Console.WriteLine($"Safe list count: {safeList.Count}"); // 1
}
}
ผลลัพธ์
nullList == null: True
Error: Object reference not set to an instance of an object.
--- วิธีตรวจสอบ Null อย่างปลอดภัย ---
Count (safe): 0
เป็น null
Safe list count: 1
Null List vs Empty List - ตารางเปรียบเทียบ
| การดำเนินการ | Empty List (new List()) | Null List (null) |
|---|---|---|
list.Count | 0 | 💥 NullReferenceException |
list.Add() | ทำงานได้ | 💥 NullReferenceException |
foreach | ไม่รัน body (ปลอดภัย) | 💥 NullReferenceException |
list.Any() | false | 💥 NullReferenceException |
list?.Count | 0 | null (ใช้ ?? 0 ได้) |
list ?? [] | list เดิม | Empty List ใหม่ |
Best Practices: หลีกเลี่ยง Null List
1. Initialize ทันทีที่ประกาศ
// Good
List items = new List();
// หรือ C# 12+
List items = [];
2. คืน Empty List แทน null ใน Method
public List GetItems()
{
if (_cache == null) return new List(); // หรือ []
return _cache;
}
3. ใช้ Null Object Pattern
// แทนที่จะคืน null
return _items ?? EmptyList.Instance;
public static class EmptyList
{
public static readonly List Instance = new List();
}
4. ใช้ ?? และ ?. ใน Caller Side
// แทน
if (list != null) { foreach (var x in list) ... }
// ใช้
foreach (var x in list ?? Enumerable.Empty()) { ... }
// หรือ
foreach (var x in list ?? []) { ... } // C# 12+
ข้อควรระวัง
- Local Variable ต้อง Initialize ก่อนใช้ (Compiler บังคับ)
- Field/Property ของ Class จะเป็น null อัตโนมัติหากไม่ Initialize
List<T>เป็น Reference Type - การ Assign จะ Copy Reference ไม่ใช่ Copy Data- ใช้
ArgumentNullException.ThrowIfNull(list)(.NET 6+) ใน Method Parameter