System.NullReferenceException は、C# で一番よく見る例外のひとつ。「オブジェクト参照がオブジェクト インスタンスに設定されていません」と出て、処理が止まる。
この記事では、よくある発生原因と現場で使える対策をざっくり逆引きできるようにまとめる。
NullReferenceException の本体はシンプルで、null のままの参照に対してメンバーアクセスしたときに起きる。
string name = null;
int len = name.Length; // NullReferenceException
対策の型もだいたい決まっている。
User user = null;
// どこかで取得失敗して null のまま
Console.WriteLine(user.Name);
API レスポンス、DB 検索、辞書の取得失敗あとで起きやすい。
// order はあるが Customer が null
var city = order.Customer.Address.City;
「最後のプロパティが怪しい」と思いがちだが、途中の参照が null なことが多い。
var users = new List<User?> { new User("A"), null };
foreach (var u in users)
{
Console.WriteLine(u.Name); // 2件目で例外
}
public event Action? OnSaved;
public void Save()
{
OnSaved(); // 購読者がいないと NullReferenceException
}
コンストラクタ注入漏れ、オプションクラス未バインド、GetService で null を受け取ってそのまま使う、など。アプリ起動直後ではなく、特定画面・特定リクエストだけ落ちることもある。
a.b.c なら a と a.b)ログに「どの ID のとき落ちたか」が残っていると一気に楽になる。
var city = order?.Customer?.Address?.City;
if (string.IsNullOrEmpty(city))
{
return;
}
ArgumentNullException.ThrowIfNull(user);
ArgumentNullException.ThrowIfNull(user.Name);
入り口で落とした方が、後段の NullReferenceException より原因がわかりやすい。
OnSaved?.Invoke();
#nullable enable
User? user = FindUser(id);
if (user is null) return;
Console.WriteLine(user.Name); // ここでは user は非 null
コンパイル時点で「null の可能性がある」と怒ってくれるので、実行時例外を減らせる。
catch (NullReferenceException) で握りつぶす(原因が見えなくなる)? 付けて黙らせる(本来必須の値が黙って欠ける)!(null 免除演算子)を根拠なく多用するNullReferenceException は「null に対するメンバーアクセス」? と早期 return、本丸は初期化・バリデーション・nullable 参照型似た系統だと、ArgumentNullException や nullable 関連の警告もセットで押さえておくと実務で困りにくい。