1. ホーム
  2. c#

[解決済み] x is null」と「x == null」の違いは何ですか?

2022-03-21 02:46:28

質問

C# 7 では

if (x is null) return;

ではなく

if (x == null) return;

新しい方法(前者の例)を使うことで、古い方法より優れている点はありますか?

セマンティクスに違いはありますか?

好みの問題なのでしょうか?もしそうでないなら、どのような場合にどちらを使うべきでしょうか?

参考にしてください。 C# 7.0の新機能 .

解決するには?

更新してください。 Roslynコンパイラーが更新され、2つの演算子の動作が同じになりました。 オーバーロードされた等式演算子がない場合 . をご覧ください。 現在のコンパイラの結果にあるコード ( M1M2 は、オーバーロードされた等価比較器がない場合に何が起こるかを示しています。両者とも、よりパフォーマンスの高い == という動作をします。オーバーロードされた等価比較器がある場合。 の場合、コードはまだ異なっています。 .

Roslynコンパイラの古いバージョンについては、以下の解析を参照してください。


について null は、C# 6で慣れ親しんできたものと違いはありません。しかし null を別の定数に変更します。

たとえば、こんな感じです。

Test(1);

public void Test(object o)
{
    if (o is 1) Console.WriteLine("a");
    else Console.WriteLine("b");
}

このテストでは a . と比較すると o == (object)1 と書くと、とんでもない違いが出てきます。 is は、比較の相手側の型を考慮します。かっこいいですね。

私は、この == null vs. is null の定型パターンは、「たまたま」とても身近なものであるだけで、その構文が is 演算子と等号演算子が同じ結果になる。


として ヴィーク とコメントした。 is null コール System.Object::Equals(object, object) ここで == コール ceq .

のIL is :

IL_0000: ldarg.1              // Load argument 1 onto the stack
IL_0001: ldnull               // Push a null reference on the stack
IL_0002: call bool [mscorlib]System.Object::Equals(object, object) // Call method indicated on the stack with arguments
IL_0007: ret                  // Return from method, possibly with a value

のIL == :

IL_0000: ldarg.1              // Load argument 1 onto the stack
IL_0001: ldnull               // Push a null reference on the stack
IL_0002: ceq                  // Push 1 (of type int32) if value1 equals value2, else push 0
IL_0004: ret                  // Return from method, possibly with a value

について話しているので null であるため、違いはありません。 のインスタンスにのみ差異を生じます。 . これは、等号演算子をオーバーロードした場合に変更される可能性があります。