Code Fix

初級

Object reference not set エラー(null参照)の原因

C#で最も有名な実行時エラーです。nullのままの変数のメンバーにアクセスしようとすると発生します。

エラーメッセージの読み方

Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
System
名前空間 — System なら標準の基本例外です
NullReferenceException
例外クラス — 何が起きたか。ここを検索するのが最短です
Object reference not set to an instance of an object.
詳細メッセージ — どの値が問題だったか
at Program.Main(String[] args) in Program.cs:line 4
発生箇所 — スタックトレースの先頭行

このエラーが出る典型パターン

パターン1

 1  class Program {
 2      static void Main(string[] args) {
 3          string s = null  ;
                          ^
 4          System.Console.WriteLine(s.Length);
 5      }
 6  }
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object. at Program.Main(String[] args) in Program.cs:line 4

sがnullのままLengthにアクセスしています。nullは「何もない」ことを表す値で、メンバーを持ちません。

直し方: null を "hi" にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  class Program {
 2      static void Main(string[] args) {
 3          string[] names = new string[3];
 4          names[0] = null  ;
                          ^
 5          System.Console.WriteLine(names[0].ToUpper());
 6      }
 7  }
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object. at Program.Main(String[] args) in Program.cs:line 5

string配列は要素をnullで初期化します。代入し忘れた要素をそのまま使うとNullReferenceExceptionになります。

直し方: null を "Al" にします。

この問題を解いてみる →

パターン3

 1  class Program {
 2      static string Find(bool ok) {
 3          if (ok) return "yes";
 4          return null;
                     ^
 5      }
 6      static void Main(string[] args) {
 7          string r = Find(false);
 8          System.Console.WriteLine(r.Length);
 9      }
10  }
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object. at Program.Main(String[] args) in Program.cs:line 8

メソッドがnullを返す経路があると、呼び出し側でチェックせずに使った瞬間に例外が起きます。

直し方: null を "no" にします。

この問題を解いてみる →

パターン4

 1  class Program {
 2      static void Main(string[] args) {
 3          string msg = null  ;
                            ^
 4          System.Console.WriteLine(msg.Length);
 5      }
 6  }
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object. at Program.Main(String[] args) in Program.cs:line 4

msgがnullのままLengthにアクセスするとNullReferenceExceptionになります。

直し方: null を "go" にします。

この問題を解いてみる →

パターン5

 1  class Program {
 2      static string Lookup(bool found) {
 3          if (found) return "item";
 4          return null  ;
                      ^
 5      }
 6      static void Main(string[] args) {
 7          string r = Lookup(false);
 8          System.Console.WriteLine(r.Length);
 9      }
10  }
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object. at Program.Main(String[] args) in Program.cs:line 8

メソッドがnullを返す経路があると、呼び出し側でチェックせず使った瞬間に例外になります。

直し方: null を "none" にします。

この問題を解いてみる →

よくある誤解

nullは「何もない」ことを表す値そのもので、メンバーを持ちません。宣言しただけの参照型変数や、代入し忘れた配列の要素はnullのままです。

実務での勘所

この例外の設計上の根本原因(nullを許すあらゆる参照型変数)は、null参照の発明者であるTony Hoare自身が後年「10億ドルの失敗」と呼んで悔いたことで有名です。C# 8以降はNullable Reference Typesという機能(プロジェクトで#nullable enableを設定)により、string(null不可のつもり)とstring?(nullを許容)を型として区別できるようになり、null非許容の変数にnullを代入しようとするコードをコンパイル時の警告として検出できます。実行時まで待たずに、この種のミスの多くを事前に見つけられるようになりました。

演習をはじめる

関連するエラー

他の言語ではどうなるか

広告
広告スロット(未設定)