2010-12-29 11 views
19

は、次のクラスを考えてみましょう:演算子==メソッドでnullをチェックする方法は?

public class Code : IEquatable<Code> 
{ 
    public string Value { get; set; } 

    public override bool Equals(object obj) 
    { 
     return Equals(obj as Code); 
    } 

    public override bool Equals(Code code) 
    { 
     if (code == null) return false; 
     return this.Value == code.Value; 
    } 

    public static bool operator ==(Code a, Code b) 
    { 
     if (a == null) return b == null; 
     return a.Equals(b); 
    } 

    public static bool operator !=(Code a, Code b) 
    { 
     if (a == null) return b!= null; 
     return !a.Equals(b); 
    } 

    // rest of the class here 
} 

==方法を使用してみてください:それはnullをチェックするとき==方法は、自分自身を呼び出すため

Code a = new Code(); 
Code b = new Code(); 
Console.WriteLine("The same? {0}", a==b); 

結果はStackOverflowExceptionです。

しかし、私はnullをチェックアウト取る場合:

public static bool operator ==(Code a, Code b) 
{ 
    return a.Equals(b); 
} 

を私はNullReferenceExceptionを入手!

これらのメソッドを定義する正しい方法は何ですか?

答えて

26

をまた==のnull`なので方が高速です(object)a == null

+0

現在、より多くのupvotesを持っているこのソリューションの代替案がありますので、 'ReferenceEquals' op ==実装がより2倍以上の時間を要するほど、'(オブジェクト)a == null'はより高速なコードになります。 '(オブジェクト)a == null'を使用して同等のものとして長くなります。 'Equals'に対しても同じコードを使用すると、この型で使用するすべての(Distinct()、' Dictionary <> '、' HashSet <> '、' ToLookup'などでノックオン効果が得られます)キーとして。 –

+0

'ReferenceEquals'でperf問題を再現するのに興味のあるLinqpadマイクロベンチマーク:https://github.com/EamonNerbonne/ValueUtils/blob/master/NullCheckBenchmark.linq明らかにCLRがインライン展開することもありますので、運が良ければ問題ありません。 –

関連する問題