いわゆるnull
参照エラー(一部では「ヌルポエラー」とも言われる)は、プログラムのバグの原因でもっとも多い問題の一種です。プログラマーにとって天敵とも言える存在かもしれません。
しかし、C#には null
参照エラーをスマートに解決するためのシンタックスシュガー(糖衣構文)があります。
この記事では、C#で null
参照をスマートに実装する構文を紹介します。
スポンサーリンク
そもそも、なんでnullが必要なの?
null
は古くからあるプログラミング言語に取り入れられている概念です。
すべてのプログラマーにとって null
はお友達みたいなものです。(違う?)
しかし、null
のせいで障害が発生するなら、いっそのこと null
という概念自体を無くしてしまえと思った人も少なくないでしょう。
実際にObjective-C
のようなプログラミング言語では、null
の変数に対して関数を呼び出しても、例外を発生させない仕様が採用されましたが、あまり受け入れられませんでした。
null は重要な概念!nullとうまく付き合う
null
はプログラミングにおける重要な概念で、特定の状態や条件を明示的に表現するのに役立ちます。たとえば、オプショナルな値を扱ったり、エラーや異常状態を示したり、未初期化の状態を表現したりする際にはnull
が利用されます。一方で、null
を適切に扱わないと null
参照エラーが発生し、プログラムの安定性に影響を与える可能性があります。しかし、このようなエラーは、適切な null
チェックやエラー処理を行うことで防ぐことができます。null
はコードの意図を明確に伝え、プログラムのロジックを簡潔に保つために不可欠な要素であり、それを理解し適切に扱うことは、安全で効率的なコードを書くために重要です。
前置きが長くなってしまいました。次からC#で null
をスマートに扱う方法を紹介します。
null許容型
C#でプログラミングする上で、null許容型の知識は必須です。
null許容型は、値型(int, double, boolなど)の変数が null
値を持つことができるようにする特別な型です。これは、?
修飾子を使用して宣言されます。
C#では、このnull許容型によってあらゆる型の変数に null
を代入可能です。
int? num; //`?`修飾子で宣言された変数には初期値にnullが入る
null許容型のメリット
null許容型のメリットを3つ挙げましょう。
未初期化の状態を明示できる
null許容型を使用することで、変数がまだ値を持っていない状態を明示できます。
通常の値型では、例えばint
の場合は「0」、DateTime
の場合は「0001/01/01」といったデフォルトの初期値が設定されます。しかし、これらの初期値が意図的に設定されたのか、それとも単に未初期化のデフォルト値なのかを区別するのは困難です。 対して、null許容型は null
値を利用して未初期化状態を明示的に表現することができます。
参照型でもnull許容型を利用できる
?
修飾子を利用することで、参照型の変数でもnull許容型を宣言することが可能です。
参照型では、null許容型の導入前から以下のように変数にnull
を設定することができました。
Person person = null;
しかし、プログラムが複雑化すると、変数がnull
の値を取り得るかどうかを判断するのが困難になります。これにより、if (person != null)
のようにnull
参照エラーを避けるための分岐処理が頻繁に登場し、コードの可読性が低下することがありました。
?
修飾子を使って参照型のnull許容型を宣言することで、変数がnull
値を取り得る可能性を明示できます。これにより、不必要なnull
判定のロジックを削減し、コードの可読性と管理性を向上させることができます。
データベースの連携がしやすい
データベースとのやり取りにおいて、特定のフィールドが値を持っていない(つまりNULL)ことを示す必要があります。C#のnull許容型は、データベースのNULL値を適切に表現し、ハンドルするのに役立ちます。これにより、データベースとの連携がより簡単かつ効果的に行えます。
null条件演算子
null条件演算子を使って、オブジェクトが null
でない場合にのみメソッドを呼び出すことができます。これは、プログラムの安全性を向上させ、null
参照例外を防ぐのに役立ちます。
以下は、null条件演算子の使用方法です。
Person? person = new Person();
person = null;
var result = person?.SayHello(); // result = null
上記のコードでは、person
オブジェクトがnullでない場合にのみ、SayHello
メソッドが呼び出されます。person
が null
の場合、?.
演算子はnull
を返し、SayHello
メソッドは呼び出されません。
null条件演算子は、インデクサアクセスにも使用可能です。
次のコードは、collectionオブジェクトが null
の場合、インデクサアクセスはスキップされ null
が返却されます。
StringCollection collection = null;
var item = collection?[1];
null合体演算子
この演算子は、変数が null
であるかどうかをチェックし、null
でない場合はその値を、null
の場合は別のデフォルト値を返します。これにより、プログラマーは null
参照エラーに関する問題をスマートに解決できます。
以下は「null 合体演算子」の基本的な使い方の例です。
変数 a
が null
であるため、??
の右側に書いたデフォルト値が返ります。
int? a = null;
int b = a ?? 0; // aがnullなので、bは0になります
スポンサーリンク
null合体代入演算子
null
合体代入 (??=) が導入されました。これにより、変数が null
の場合にのみ値を代入することができます。
「null 合体演算子」よりも、代入処理はスッキリ書けます。
string name1 = null;
name1 ??= "foo"; // name1がnullなので、"foo"が代入されます
string name2 = "bar";
name2 ??= "foo"; // name2にはnull以外の値が設定済みのため、代入されず値は"bar"のままです。
まとめ
C#でnull
参照エラーを回避し、null
とうまく付き合うための糖衣構文を紹介してきました。
この記事では、次のことを紹介しています。
- nullは未初期化を表す重要な概念である。nullをうまく使ったプログラミングを心がけよう
- C#には「null許容型」「null条件演算子」「null合体演算子」などの便利な型や糖衣構文が存在する
0 件のコメント:
コメントを投稿