2010-12-29 11 views
19

Рассмотрим следующий класс:Как проверить значение null в методе operator ==?

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 
} 

Теперь попробуйте использовать метод ==:

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

В результате StackOverflowException, так как метод == называет себя, когда он проверяет нуль.

Но если я вынимаю нулевой чек:

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

я получаю NullReferenceException!

Каков правильный способ определения этих методов?

ответ

26

Вы также можете использовать (object)a == null

+0

Существует альтернатива этому решению, которое в настоящее время имеет больше приоритетов, поэтому позвольте мне заметить, что '(object) a == null' приводит к более быстрому коду, в той мере, в какой реализация' ReferenceEquals' op == заняла более двух раз длинный как эквивалент, использующий '(object) a == null'. Если вы используете тот же код и для 'Equals', это может иметь эффект постукивания в каждом' Distinct() ',' Dictionary <> ',' HashSet <> ',' ToLookup' и т. Д., Которые вы используете с этим типом как ключ. –

+0

Микрочип Linqpad для тех, кто заинтересован в репликации перфекционной проблемы с помощью 'ReferenceEquals': https://github.com/EamonNerbonne/ValueUtils/blob/master/NullCheckBenchmark.linq. Обратите внимание, что, по-видимому, иногда CLR делает это, поэтому, если вам повезет, это не имеет значения. –

Смежные вопросы