Laden...

Eigener Operator, Problem mit null-Abfrage

Erstellt von JunkyXL vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.173 Views
JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 17 Jahren
Eigener Operator, Problem mit null-Abfrage

Hallo,
ich habe in meiner Klasse die Operatoren == und != 'eingebaut' und habe erst jetzt festgestellt, dass wenn ich ein Objekt meiner Klasse mit null vergleiche es zu einer NullReference Exception kommt, da ich ja das Value-Property nehme um einen Vergleich durchzuführen.
Wie löse ich das nun am besten um auf ein sauberes Ergebnis zu kommen, wenn ich auf null prüfe?

public static bool operator ==(Month month1, Month month2)
{
    return month1.Value == month2.Value;
}

public static bool operator !=(Month month1, Month month2)
{
    return month1.Value != month2.Value;
}

Danke für jede Hilfe
Junky

M
1.439 Beiträge seit 2005
vor 17 Jahren

Zuvor auf null prüfen und gegebenenfalls false zurückgeben.

O
778 Beiträge seit 2007
vor 17 Jahren

oder ArgumentNullException, hängt davon ab, wie du's haben willst...

JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 17 Jahren

Das gibt nen Stackoverflow wenn ich das mache 😉
Da ich ja damit wieder auf meinen definierten Operator zugreife

M
1.439 Beiträge seit 2005
vor 17 Jahren

object.ReferenceEquals()

ArgumentNullException solltest du nicht werfen, da dies keiner erwartet und sonst auch keiner mehr auf null prüfen kann.

O
778 Beiträge seit 2007
vor 17 Jahren

object.ReferenceEquals()

Meiner Meinung nach dann aber lieber IEquatable<Month> implementieren und .equals() aufrufen, aber vorher testen wegen Null...

//edit: Verbessert auch die Datenverarbeitung der Klasse m.E. immens

S
8.746 Beiträge seit 2005
vor 17 Jahren

Noch ein Tipp: Statt nur den Operator zu überschreiben, solltest du object.Equals() überschreiben und zudem eine typisiere Equals()-Version bereitstellen.

Grundsätzlich ist aber dein Code u.U. gefährlich denn:

Overriding operator == in non-immutable types is not recommended.

Ein Monat immutable zu implementieren ist aber einfach und auch naheliegend.

T
512 Beiträge seit 2006
vor 17 Jahren

Kannst auch struct draus machen, dann gibts kein null 😉

e.f.q.

Aus Falschem folgt Beliebiges

JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 17 Jahren

Danke.
Hab das jetzt so gelöst und funktioniert auch wie man es gewohnt ist:

public static bool operator ==(Month month1, Month month2)
{
    if (object.ReferenceEquals(month2, null) == true)
    {
        return object.ReferenceEquals(month1, month2);
    }

    return month1.Value == month2.Value;
}

public static bool operator !=(Month month1, Month month2)
{
    if (object.ReferenceEquals(month2, null) == true)
    {
        return !(object.ReferenceEquals(month1, month2));
    }

    return month1.Value != month2.Value;
}
M
1.439 Beiträge seit 2005
vor 17 Jahren

Original von onlinegurke
Meiner Meinung nach dann aber lieber IEquatable<Month> implementieren und .equals() aufrufen, aber vorher testen wegen Null...

Ja aber wie willst du auf null prüfen, wenn du den == operator überladen hast?
Equals sollte man sowieso überschreiben, wenn man den == und != Operator überschreibt.

S
8.746 Beiträge seit 2005
vor 17 Jahren

Original von onlinegurke
Meiner Meinung nach dann aber lieber IEquatable<Month> implementieren und .equals() aufrufen, aber vorher testen wegen Null...

Bringt hier wenig. Die Basisimplementierung von == ist eben object.Equals() (Wertetypen) bzw. object.ReferenceEquals().

JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 17 Jahren

Equals zu überschreiben hat mir der Compiler empfohlen und ich hasse Warnungen auch wenn sie nicht weiter stören. Also habe ich Equals schon drin 😉

O
778 Beiträge seit 2007
vor 17 Jahren

@marsgk

An dieser Stelle kann ich nicht mit Source dienen, weil das eine Feinheit von C# ist, die ich nicht kenne (ich programmiere VB.NET). Aber der Tatsache geschuldet, dass C# und VB.NET vom Funktionsumfang immer mindestens identisch sind, gehe ich einfach mal davon aus, dass man das, was man in VB.NET umsetzen kann auch in C# umsetzen kann und die Programmiertechniken nicht so unterschiedlich sind. In VB.NET würde ich in etwa sowas schreiben:


Public Shared Overloads Operator =(arg1 as Month,arg2 as Month) as Boolean
  If arg1 [B]is[/B] Nothing Then return arg2 is Nothing
  Return arg1.equals(arg2)
End Operator

Public Overloads Function Equals(other as Month) as Boolean implements IEquatable(of Month).Equals
if other is nothing then return False
return Value.equals(other.Value)
End Function

O
778 Beiträge seit 2007
vor 17 Jahren

Wenn ich mal so frei sein darf, würd ich doch mal vermuten, hinter den Instanzen der Klasse Month stecken Monate. Warum in aller Welt sollte man dann den ==-Operator mit Object.ReferenceEquals() implementieren, das wär doch sowas von unintuitiv. Dezember ist nicht Dezember weil ist andere Instanz von Dezember...

JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 17 Jahren

Dezember IST Dezember
das ist der Sinn meiner Implementierung der == und != Operatoren..
ein Jahr hat nun mal nur 12 Monate.

M
1.439 Beiträge seit 2005
vor 17 Jahren

Das Object.ReferenceEquals() dient hier ja nur der Überprüfung auf null.

S
8.746 Beiträge seit 2005
vor 17 Jahren

Wie gesagt:

Wenn ein Referenztyp Wertesemantik haben soll, dann IMMER das Objekt verriegeln (immutable). Den Gleichheitsoperator mit Equals() zu verbinden ist nur die halbe Miete....