Laden...

[gelöst] Überladen von "==": Null abfangen?

Erstellt von HeinzTomato vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.915 Views
HeinzTomato Themenstarter:in
345 Beiträge seit 2005
vor 14 Jahren
[gelöst] Überladen von "==": Null abfangen?

Hallo allerseits.

Ich habe um zwei Objekte einer eigenen Klasse zu vergleichen den ==-Operator und !=Operator überladen:

 
public class BankData {
     public static bool operator ==(BankData data1, BankData data2)
        {    
                return data1.NationalAccountNumber == data2.NationalAccountNumber &&
                    data1.NationalBankCode == data2.NationalBankCode &&
                    data1.Bic == data2.Bic &&
                    data1.Iban == data2.Iban;            
        }

        public static bool operator !=(BankData data1, BankData data2)
        {
            return data1.NationalAccountNumber != data2.NationalAccountNumber ||
                data1.NationalBankCode != data2.NationalBankCode ||
                data1.Bic != data2.Bic ||
                data1.Iban != data2.Iban;
        }
}

Wenn ich den nun mit zwei Objekten verwende klappt das auch:

BankData bd1=new BankData();
BankData bd2=new BankData();
BankData bd3=new BankData();
bd1.BIC="BIC1";
bd2.BIC="BIC2";
bd3.BIC="BIC1";
bd1.Iban="Iban1";
bd2.Iban="Iban2";
bd3.Iban="Iban1";
bd1.NationalBankCode="1220";
bd2.NationalBankCode="1223";
bd3.NationalBankCode="1220";
bd1.NationaAccountNumber="222";
bd2.NationaAccountNumber="242";
bd3.NationaAccountNumber="222";

if (bd1==bd2) {} // FALSE
if (bd1==b3) {} // TRUE

Nun habe ich aber mehrere Stellen, an denen ich prüfe, ob das Objekt null ist:

if (bd1==null) {
// whatever
}

Und genau da knallt es, da er ja auch hier in meinen überladenen operator springt. Gibt es eine Lösung für dieses Dilemma?

Mein Haus, mein Viertel, mein Blog

Gelöschter Account
vor 14 Jahren

Gibt es eine Lösung für dieses Dilemma?

ja, deine überladungen sollten korrekt implementiert sein. du solltest in denen zuerst die "null" möglichkeiten überprüfen...

außerdem...

public static bool operator !=(BankData data1, BankData data2)
        {
            return data1.NationalAccountNumber != data2.NationalAccountNumber ||
                data1.NationalBankCode != data2.NationalBankCode ||
                data1.Bic != data2.Bic ||
                data1.Iban != data2.Iban;
        }

kannst du auch:

public static bool operator !=(BankData data1, BankData data2)
        {
            return !(data1 == data2);
        }
HeinzTomato Themenstarter:in
345 Beiträge seit 2005
vor 14 Jahren

Hmm. Den Gedanken hatte ich natürlich auch schon... Wenn ich aber folgendes mache:


     public static bool operator ==(BankData data1, BankData data2)
        {
          if (data1==null) {
             return data2==null;
           }
           else
           {
               return data1.NationalAccountNumber == data2.NationalAccountNumber &&
                   data1.NationalBankCode == data2.NationalBankCode &&
                   data1.Bic == data2.Bic &&
                   data1.Iban == data2.Iban;
           }
        }


führt die Abfrage "if (data1==null)" zu einer Endlosschleife, weil er hierfür erneut in diesen Opeator springt.

Mein Haus, mein Viertel, mein Blog

G
4 Beiträge seit 2009
vor 14 Jahren

Hallo HeinzTomato,

du sollte für den Fall das einer der beiden Werte null ist auch false zurückgeben und nicht einen erneuten Vergleich machen.


if (data1==null || data2==null) 
{
       return false;
}

HeinzTomato Themenstarter:in
345 Beiträge seit 2005
vor 14 Jahren

ja, aber

if (data1==null || data2==null)

führt ja schon zur Endlosschleife...

Mein Haus, mein Viertel, mein Blog

916 Beiträge seit 2008
vor 14 Jahren

Überprüf doch einfach ob


if (data1==null && data2==null)
    return true; //null==data1 data1==null

if (data1==null || data2==null)
    return false;

....

Deckt das nicht alle Möglichkeiten ab?

Again what learned...

HeinzTomato Themenstarter:in
345 Beiträge seit 2005
vor 14 Jahren

Bleibt das Problem: Sobald ich data1==null schreibe gibts ne Endlosschleife.

Ich habe es nun wie folgt gelöst:

object data1Object = (object)data1;            
object data2Object = (object)data2;
if (data1Object == null)
{
  return data2Object == null;
}

das Geheimnis ist also das Casten als Objekt. Gibts ne schickere Lösung?

Mein Haus, mein Viertel, mein Blog

2.891 Beiträge seit 2004
vor 14 Jahren

Hallo HeinzTomato,

wie wär's denn mit Object.ReferenceEquals:

if (Object.ReferenceEquals(data1,null)) { ... }

Gruß,
dN!3L

916 Beiträge seit 2008
vor 14 Jahren

Die Idee ist glaub ich die Zielführendste...

Again what learned...

L
416 Beiträge seit 2008
vor 14 Jahren

Wie wärs mit einer IsNull-Methode für die Klasse in der zb. die AccountNumber auf null geprüft wird?

Ich fände


if (data1.IsNull() | data2.IsNull())
{
       return false;
}  

am leserlichsten.

edit: Ist natürlich Quatsch der Vorschlag ... hätte es vorher testen sollen dann hätte ich mich hier nicht blamiert 😉.

Gelöschter Account
vor 14 Jahren

@Lennart:

wenn data1 null ist dann kannst du auch keine methoden aufrufen....

3.971 Beiträge seit 2006
vor 14 Jahren

IsNull-Methode macht nur bei Werttypen sinn. Dort wäre aber eventuell IsZero von der Namensgebung angebrachter.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

S
248 Beiträge seit 2008
vor 14 Jahren

Wie dN!3L schon geschrieben hat ist ReferenceEquals (oder der cast nach Object) eine Lösung, hier in einem einfachen Beispiel:

		class Point
		{
			public double X { get; set; }
			public double Y { get; set; }

			public static bool operator ==(Point a, Point b)
			{
				if (ReferenceEquals(a, b))
				{
					return true;
				}
				if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
				{
					return false;
				}
				return ((a.X == b.X) && (a.Y == b.Y));
			}

			public static bool operator !=(Point a, Point b)
			{
				return (!(a == b));
			}
		}

Spooky

HeinzTomato Themenstarter:in
345 Beiträge seit 2005
vor 14 Jahren

Danke, habe ObjectReferenceEquals verwendet.

Mein Haus, mein Viertel, mein Blog

5.299 Beiträge seit 2008
vor 14 Jahren

Wie wärs mit einer IsNull-Methode für die Klasse in der zb. die AccountNumber auf null geprüft wird?

Ich fände

  
if (data1.IsNull() | data2.IsNull())  
{  
       return false;  
}    
  

am leserlichsten.

edit: Ist natürlich Quatsch der Vorschlag ... hätte es vorher testen sollen dann hätte ich mich hier nicht blamiert 😉.

Noo - ist doch kein Quatsch!
Wie findste meine Extension?


namespace System {

   /// <summary> Extension-Methods für alle Klassen </summary>
   public static class ObjectX {

      public static bool IsNull(this object Subj) {
         return object.ReferenceEquals(Subj, null);
      }

   }
}


Die kanndas 😁

Der frühe Apfel fängt den Wurm.

2.891 Beiträge seit 2004
vor 14 Jahren

Noo - ist doch kein Quatsch!
Wie findste meine Extension?

Mehr zum Thema Methoden auch an null aufrufen durch Extension Methods gibt's auch unter Extension Methods und NullReferenceExceptions

Gruß,
dN!3L