タイトルにもありますが、C#で== null
とis null
でどちらの方が高効率でしょうか?もし、このサイトの説明の様に、==
演算子が継承されていて、null
と比較した時にtrue
が返された場合大きな問題になります。なので、is null
やSystem.Object.ReferenceEquals(object, object)
等を利用して参照が確実にnull
かどうか判定する必要があると思うのですが、保守性、速度等から見て全ての== null
をis null
に変えるのは、効率的と言えますか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
C#
1using System; 2using System.Diagnostics; 3using System.Linq; 4 5namespace ConsoleApp1 6{ 7 class Program 8 { 9 static void Main(string[] args) 10 { 11 Console.WriteLine(new Nullable<int>() == null); 12 Console.WriteLine(new Nullable<int>() is null); 13 Console.WriteLine(ReferenceEquals(new Nullable<int>(), null)); 14 for (int i = 0; i < 3; i++) 15 { 16 MeasureTime("==", a => a == null); 17 MeasureTime("is", a => a is null); 18 } 19 Console.ReadKey(); 20 } 21 22 static void MeasureTime(string title, Func<int?, bool> action) 23 { 24 var stopwatch = new Stopwatch(); 25 stopwatch.Start(); 26 var result = Enumerable 27 .Range(0, 100000000) 28 .Select(a => (int?)a) 29 .Concat(new[] { default(int?) }) 30 .TakeWhile(a => !action(a)) 31 .Count(); 32 stopwatch.Stop(); 33 Console.WriteLine($"■ {title} ■"); 34 Console.WriteLine($"ループ回数: {result}"); 35 Console.WriteLine($"時間: {stopwatch.Elapsed}"); 36 } 37 } 38}
上記コードで計測してみたところ、うちでは次のようになりました。
True True True ■ == ■ ループ回数: 100000000 時間: 00:00:05.3188705 ■ is ■ ループ回数: 100000000 時間: 00:00:04.4728642 ■ == ■ ループ回数: 100000000 時間: 00:00:04.9455408 ■ is ■ ループ回数: 100000000 時間: 00:00:04.9704037 ■ == ■ ループ回数: 100000000 時間: 00:00:04.9747958 ■ is ■ ループ回数: 100000000 時間: 00:00:05.4253197
効率面から言えば、誤差の方が大きいので全く気にする必要はありません。
また、new Nullable<int>()
に対して ==
is
ReferenceEquals
の全てが true
を返しています。オブジェクトを作成しているので、当然 null ではないのになぜこうなるかと言うと、Nullable<T>
は値型なので、比較関数に引数として渡される時に値のコピーが発生しますが、この時コピーの代わりに該当オブジェクトではなく null が渡されるからです。
したがって、Nullable<T>
ではこの三つを区別する必要はありません。クラスによっては区別する必要がでてきますから、それはその時々の状況に合わせて考えてください。
投稿2019/03/08 04:10
総合スコア28662
0
こんにちは。
equalityのオーバーロードが実装されていない型を相手にする場合はどちらの記述でも全く同じ結果になります。
オーバーロードされているものを比較する場合は、比較処理が走らないis null
の方が低コストです。といっても、比較が非常にヘビーな実装でもない限り誤差すら出ない程度だと思いますが。
問題はそこではなくて、「あなたがどちらの結果を求めているのか」だと思います。
equalityのオーバーロードによって実装されたオブジェクト特有の比較による結果を利用したいなら==
を使う以外の選択肢は無いですし、単純にnull
ではないことを確認したいならis null
の方が確実な結果を得られます。
例えば使用中のサードパーティライブラリが突然equalityをオーバーロードして、比較の結果が変わることを是とするか非とするかで決めないと後々訳が分からなくなります。
保守性、速度等を評価基準にする場合では基本的に書き換える価値は全くないと考えます。
投稿2019/03/08 04:08
総合スコア4228
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/08 04:26
2019/03/08 04:36
2019/03/08 04:41
2019/03/08 04:44
2019/03/08 04:47
2019/03/08 04:58
2019/03/08 05:00
2019/03/08 05:04
2019/03/08 05:07
2019/03/08 05:07
0
気になるなら、計測しなよ。
せいぜい、これからは気をつける、速度が絶対必要なら治すぐらいのことかと。
投稿2019/03/08 04:09
総合スコア1984
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
Program.cs
1using System; 2#nullable enable 3 4var a1 = new A(); 5Console.WriteLine(a1 is null); 6A? a2 = new A(); 7Console.WriteLine(a2 is null); 8Console.WriteLine(a2 == null); 9var b1 = new B(); 10Console.WriteLine(b1 is null); 11Console.WriteLine(b1 == null); 12B? b2 = new B(); 13Console.WriteLine(b2 is null); 14Console.WriteLine(b2 == null); 15C? c = new C(); 16Console.WriteLine(c is null); 17Console.WriteLine(c == null); 18 19class A { 20 public static bool operator ==(A a1,A a2) => false; 21 public static bool operator !=(A a1,A a2) => false; 22} 23class B { 24} 25struct C{ 26}
みたいに書いたとき、
Program.cs
1A a1 = new A(); 2Console.WriteLine((object)a1 == null); 3A a2 = new A(); 4Console.WriteLine((object)a2 == null); 5Console.WriteLine(a2 == null); 6B b1 = new B(); 7Console.WriteLine(b1 == null); 8Console.WriteLine(b1 == null); 9B b2 = new B(); 10Console.WriteLine(b2 == null); 11Console.WriteLine(b2 == null); 12Nullable<C> c = default(C); 13Console.WriteLine(!c.HasValue); 14Console.WriteLine(!c.HasValue);
の様に解釈されている為、 比較対象のクラス・構造体がどういうものが意識したくないのであれば
is null
を使った方がいいのではないでしょうか?
投稿2020/12/18 00:44
総合スコア437
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/08 04:28