2009-06-25 2 views
4

Я перегружен оператор == в моем классе следующим образом:(C#) Проблемы при перегрузке оператора ==

public static bool operator ==(Table pt1, Table pt2) { 
    return Compare(pt1, pt2) == 0 && pt1.TableName == pt2.TableName; 
} 

Сравните будет работать так же, как зЬгстр делает в C++, возвращая целое число. Проблема в том, что если я сделаю if (MY_CLASS == null), он вызовет оператор my == и, следовательно, мою функцию Compare. Что такое альтернатив? поставить чек на pt1 и pt2, чтобы узнать, являются ли они нулевыми? Или просто в pt2?

+0

Я имею в виду, я даже не могу проверить, являются ли они пустыми, поскольку это создаст рекурсивный вызов для моего оператора ==. Что мне делать? –

ответ

2

Просто добавьте эту строку вашего оператора.

if ((object)pt1 == null || (object)pt2 == null) return false; 

(object) литая есть для предотвращения рекурсии (от вызова object.== вместо MY_CLASS.==

Хотя я не уверен, что из условий, которые должны возникают при сравнении null с нулем.

+0

Будет ли это работать? Я бы подумал, что приведение здесь не будет иметь никакого значения, поскольку методы переопределения являются виртуальными. –

+1

Вы не * переопределяете * ==, вы * перегружаете его. –

3

Для правильного поведения вам понадобятся нулевые проверки. Самый яркий способ добавить эту проверку, на мой взгляд, - позвонить object.ReferenceEquals(x, null), так как это прямой неполиморфный вызов метода и, по-видимому, достаточно эффективный.

12

Вы должны проверить Microsoft guidelines для реализации оператора '==', а также для переопределения 'Equals()'.

Адаптирование их примеру, вы хотите что-то вроде:

public static bool operator ==(Table a, Table b) 
{ 
    // If both are null, or both are same instance, return true. 
    if (System.Object.ReferenceEquals(a, b)) 
    { 
     return true; 
    } 

    // If one is null, but not both, return false. 
    if (((object)a == null) || ((object)b == null)) 
    { 
     return false; 
    } 

    // Return true if the fields match: 
    return Compare(a, b) == 0 && a.TableName == b.TableName; 
} 
+4

Я бы либо использовал object.ReferenceEquals в обоих местах, либо использовал приведение в обоих местах, если вы понимаете, что я имею в виду. –

2

Я задал подобный вопрос here. Посмотри на это.

public bool Equals(ClauseBE other) 
    { 
     if (this._id == other._id) 
     { 
      return true; 
     } 
     return false; 
    } 

    public override bool Equals(Object obj) 
    { 
     if (obj == null) 
     { 
      return base.Equals(obj); 
     } 

     if (!(obj is ClauseBE)) 
     { 
      throw new InvalidCastException("The 'obj' argument is not a ClauseBE object."); 
     } 

     return Equals(obj as ClauseBE); 
    } 

    public override int GetHashCode() 
    { 
     return this._id.GetHashCode(); 
    } 


    public static bool operator ==(ClauseBE a, ClauseBE b) 
    { 
     if (ReferenceEquals(a, null) && ReferenceEquals(b, null)) 
     { 
      return true; 
     } 

     if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) 
     { 
      return false; 
     } 

     return a.Equals(b); 
    } 

    public static bool operator !=(ClauseBE a, ClauseBE b) 
    { 
     return !(a == b); 
    } 
Смежные вопросы