概要
C#のforeach文において、以下の例外を起こさせないようにする。
ハンドルされていない例外: System.NullReferenceException: オブジェクト参照がオブ ジェクト インスタンスに設定されていません。
例外が発生するソースコード例
List<string> msgList = new List<string>() { "msg1", "msg2", "msg3" }; msgList = null; foreach (string msg in msgList) { Console.WriteLine(msg); Console.WriteLine("-------------"); }
発生要因
List型の変数msgListがnullなのに、その要素を取り出そうとしているため。
対策1
- 拡張関数を使用する。
参考サイト:【C#】foreach null チェック | demicadeのブログ
// 拡張関数を用意 public static class IEnumerableExtension { public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> collection) { return collection ?? Enumerable.Empty<T>(); } }
static void Main(string[] args) { List<string> msgList = new List<string>() { "msg1", "msg2", "msg3" }; msgList = null; // 拡張関数を呼び出した状態でforeachの処理を行う foreach (string msg in msgList.OrEmptyIfNull()) { Console.WriteLine(msg); Console.WriteLine("-------------"); }
結果
======START======= ======FINISH=======
例外は発生せず、またforeachの処理は値が空のため何も実行されない。
対策2
- null合体演算を用いる。
参考サイト:?? 演算子 (C# リファレンス) | Microsoft Docs
・・・「値がnullの場合はこの値を用いる」という使い方ができる
Console.WriteLine("======START======="); msgList = null; // msgListがnullの場合はList<string>で初期化する foreach (string msg in msgList ?? new List<string>()) { Console.WriteLine(msg); Console.WriteLine("-------------"); } Console.WriteLine("======FINISH=======");
結果
======START======= ======FINISH=======
まとめ
foreachの時に限らず、様々な場面でこのnull合体演算子は使えます。
if (msgList == null){} のようなIF文を書くよりもずっとスマートに、シンプルに例外を避けられます。