2017-04-25 9 views
3

C#7でパターンマッチングを使用する方法の例がたくさんあります。それはすべて良い見えます。しかし、私には答えが見つからないような質問があります。参照または値の平等よりパターンマッチングが優先されますか?

if (a is null) 

私の質問は次のとおりです:

では、次の式を持っていると言うことではなく、C#7と参照または値の平等のパターンマッチングを使用することが好ましいですか?だからではなく、書き込みの

if (a == null) 

か:

if (a.Equals(null)) 

か:

if (object.Equals(a, null)) 

私はa is nullは最後の式のようなものを生成疑い。しかし、パターンマッチングに切り替えることが一般に好まれるだろうか?

私が間違っていて、これは主に意見ベースの質問ですが、私はこの問題を解決する決定的な答えを見つけることができませんでした。

+1

'a.Equals(null)'は、 'a'が' null'であればスローし、 'true'を返さないようにしてください。 – svick

答えて

1

次の4つのコードスニペットを考えてみましょう:

// 1 
var x = ""; 
var y = x is null; 

// 2 
var x = ""; 
var y = x.Equals(null); 

// 3 
var x = ""; 
var y = object.Equals(x, null); 

// 4 
var x = ""; 
var y = x == null; 

ILこれらのためには、それぞれ、次のとおりです。

// 1 
IL_0001: ldstr "" 
IL_0006: stloc.0 
IL_0007: ldnull 
IL_0008: ldloc.0 
IL_0009: call bool [mscorlib]System.Object::Equals(object, object) 
IL_000e: stloc.1 

// 2 
IL_0001: ldstr "" 
IL_0006: stloc.0 
IL_0007: ldloc.0 
IL_0008: ldnull 
IL_0009: call bool [mscorlib]System.Object::Equals(object, object) 
IL_000e: stloc.1 

// 3 
IL_0001: ldstr "" 
IL_0006: stloc.0 
IL_0007: ldloc.0 
IL_0008: ldnull 
IL_0009: call bool [mscorlib]System.Object::Equals(object, object) 
IL_000e: stloc.1 

// 4 
IL_0001: ldstr "" 
IL_0006: stloc.0 
IL_0007: ldloc.0 
IL_0008: ldnull 
IL_0009: ceq 
IL_000b: stloc.1 

あなたはほぼ同一のコードでは、最初の3件の結果を見ることができるように。 ==バージョンは.Equals()ではなくceqを使用します。

私はceqがより高速であると推測しています。したがって、はnullの最速テスト方法です。それを超えて、それは好みのスタイルの問題になります。

+0

#2のILは正しくありません。これは 'callvirt System.String.Equals'を使用しています。 – svick

+2

また、ILを調べるときにリリースモードを使用すると、コードが短くなり( 'stloc.0 ldloc.0'はなくなります)、コードのパフォーマンスについて少し良いアイデアが得られるはずです。 LINQPad 5(.NET 4.6)の – svick

+0

は、 '== null'と' is null'の両方で最適化をオンまたはオフにしたのと全く同じILになりますが、 '== null'は左側が可能な場合でも少し改善されます'default(string)== null'のようにコンパイル時に評価されます – Slai

関連する問題