2016-10-06 3 views
0

Ich versuche operator== in einer meiner Klassen zu implementieren. Nach dem Buch Microsoft Visual C# Schritt für Schritt soll ich es wie so schreiben:Wie vermeide ich NullReferenceException bei der Implementierung von Operator ==

using System; 
using System.Diagnostics; 

namespace EqualTest2 
{ 
    public class EqualTestClass 
    { 
     public double _x1; 

     public EqualTestClass(double x1) 
     { 
      _x1 = x1; 
     } 

     public override bool Equals(object other) 
     { 
      if (other is EqualTestClass) 
      { 
       return (Math.Abs(_x1 - ((EqualTestClass)other)._x1) < 1e-6); 
      } 
      return false; 
     } 

     public override int GetHashCode() 
     { 
      return base.GetHashCode(); 
     } 

     public static bool operator ==(EqualTestClass lhs, EqualTestClass rhs) 
     { 
      return lhs.Equals(rhs); 
     } 

     public static bool operator !=(EqualTestClass lhs, EqualTestClass rhs) 
     { 
      return !lhs.Equals(rhs); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      EqualTestClass test1 = new EqualTestClass(1.0); 
      EqualTestClass test2 = new EqualTestClass(1.0); 
      EqualTestClass test3 = new EqualTestClass(2.0); 
      EqualTestClass test4 = null; 

      Debug.WriteLine("1: {0}", test1 == test2); 
      Debug.WriteLine("2: {0}", test1 == test3); 
      Debug.WriteLine("3: {0}", test1 == test4); 
      Debug.WriteLine("4: {0}", test4 == test1); 
     } 
    } 
} 

Dieses Programm NullReferenceException auf der vierten Debug-Zeile wirft, weil lhs auf der Linie lhs.Equals(rhs) null ist. Ich kann if (lhs != null) in operator== nicht setzen, weil das endlose Rekursion verursacht (wie das Buch warnt). Also, um eine Ausnahme zu vermeiden, wenn eine Null-Instanz meiner Klasse zu vergleichen, änderte ich die Umsetzung dazu:

public static bool operator ==(EqualTestClass lhs, EqualTestClass rhs) 
    { 
     try 
     { 
      return lhs.Equals(rhs); 
     } 
     catch (NullReferenceException) 
     { 
      return false; 
     } 
    } 

    public static bool operator !=(EqualTestClass lhs, EqualTestClass rhs) 
    { 
     try 
     { 
      return !lhs.Equals(rhs); 
     } 
     catch (NullReferenceException) 
     { 
      return false; 
     } 
    } 

(Ich bin neu in C# aus einem Objective C Hintergrund kommen, wo [lhs method:argument] glücklich null zurück, wenn lhs ist null, also würde eine Ausnahme wie diese nie passieren.)

Ist diese Ausnahme-basierte Implementierung idiomatisch C# korrigieren?

Antwort

1

Ich würde vermeiden, einen try-catch-Block für Ihren Fall zu verwenden. Sie müssen nur Ihre Betreiber dies ändern:

public static bool operator ==(EqualTestClass lhs, EqualTestClass rhs) 
{ 
    return object.Equals(lhs, rhs); 
} 
public static bool operator !=(EqualTestClass lhs, EqualTestClass rhs) 
{ 
    return !object.Equals(lhs, rhs); 
} 

Dies tut das für Sie null-Überprüfung während noch Ihre überschrieben Equals() Methode aufrufen. Nach dem Quellcode für System.Object.Equals():

public static bool Equals(Object objA, Object objB) 
{ 
    if (objA==objB) { 
     return true; 
    } 
    if (objA==null || objB==null) { 
     return false; 
    } 
    return objA.Equals(objB); 
} 

Sieht aus wie die Pflege Ihrer Frage kommt.

0

Sie müssen die Argumente als Verweis auf dem Vergleich:

if (!ReferenceEquals(lhs, null)) ... 
3

mit ReferenceEquals(lhs, null) Betrachten Sie die Referenz für null für jedes Ihrer Argumente vor der Überprüfung auf Gleichheit

0

Einfach einen Null-Test ersten

zu überprüfen
if(lhs == null || rhs == null){ 

Und behandeln Sie, wie Sie wollen. (Rückgabe false oder möglicherweise true, wenn beide null sind)

.equals() erfordert ein Objekt und wird NullPointer auslösen, wenn Sie versuchen, es für ein Nullobjekt aufzurufen. Aber == funktioniert gut.

Verwandte Themen