C# での開発時、nullチェックは必ずといっていいほど行われるチェックの一つだと思います。
その際に「 a ==
null」とするか「a is null」とするか人によって結構異なるかと思います。
今回は、このnullチェックでの ==
と is の違いを踏まえてまとめていきたいと思います。
\自身のスキルを向上するには技術書で!!/
月額¥980で技術書が読み放題!!
- ビジネススキルとマインド向上したい!!
- 決断や行動を先送りにしてしまう方!!
is はいつから使えるようになったのか
私もそうですが、C# 7.0以前から開発をしている方は、基本的に「==
」(または !=)を使うことが多いと思います。
is 演算子はいつから利用できるようになったのかというと、C# 7.0 以降で利用することができるようになりました。
このis演算子は 「==
(!=)」と同様に 2つのオブジェクトを比較するのですが、型の変換が可能であるかどうかをチェックする「型テスト演算子」としての意味合いも持っています。
また、is 演算子については C#7.0以降から利用可能ですが、「is not」についてはC# 9.0で導入されています。
ですので、それ以前の場合は「! (a is null)」のように否定で対応します。
「==
」と「is」の違い
では早速、「==
」と「is」の違いを見ていきたいと思います。
C# ではデフォルトの演算子の動作をオーバーライドすることができます。それが、下記のようなサンプルクラスです
public class Sample1 {
public static bool operator == (Sample x, Sample y) => false;
public static bool operator != (Sample x, Sample y) => true;
}
上記のクラスでは、等式/不等式の演算子のデフォルトの動きをオーバーライドしています。
この例では、「==
」は常に「false」を返し、「!=」は常に「true」を返すというようにしています。
こうすると、どうなるのかというと、下記のコードで検証してみます。
Sample1 sample1 = null;
if (sample1 == null) {
Console.WriteLine("== operator");
}
if (sample1 is null) {
Console.WriteLine("is operator");
}
sample1 ==
null の部分ではオーバーライドされた演算子「operator」を実際に呼び出します。
このSample1クラスを呼び出すことで、比較処理ではオーバーライドしたoperator という重たい処理がよばれています。パフォーマンス的に無駄ですね。
しかし、 is 演算子を使うと、 オーバーライドしたカスタム実装を無視してオブジェクトをキャストするのです。
上記から、パフォーマンス的には ==
を避け、is演算子を利用した方が良いということになります。
null ではない(非null)の場合
冒頭でも述べましたが、is not がC# 9.0 から利用できるようになりました。
ですので、C# 9.0 を利用する場合のnull チェックは「is (is not)」が現時点でベストだと考えています。
C# 9.0 未満で C# 7.0以降の場合は 「is not」の代わりに「!(a is null)」のように記載すると良いかと思います。
まとめ
C#のバージョンごとにnull判定は下記のように行うと良いと思います。
C#バージョン | null判定 | 非null判定 |
---|---|---|
C#7.0 未満 | a == null | a != null |
C#7.0 以上 C#9.0 未満 | a is null | !(a is null) |
C#9.0 以上 | a is null | a is not null |
以上のことから、nullチェックは重要な役割を持っていますが、意味を知っておくとより良いかと思います。
バージョンによって使えるものと使えないものがあったりするので、そこら辺意識しておくと良いかと思います。