Frage

Ich brauche eine comparaison zwischen einem Objekt und NULL zu tun. Wenn das Objekt nicht NULL ist, ich fülle ihn mit einigen Daten.

Hier ist der Code:

 if (region != null)
 {
  ....
 }

Dies funktioniert, aber wenn Looping und irgendwann die Region Objekt Looping ist nicht null (ich kann Daten im Innern im Debug-Modus sehen). In Schritt-für-Schritt, wenn das Debuggen, gehen sie nicht in der Anweisung IF ... Wenn ich eine Schnell Uhr mit diesem folgenden Ausdruck zu tun: Ich habe die (Region == null) return false sehen, AND (Region = null! zurück) zu falsch ... , warum und wie?

Aktualisieren

Jemand weist darauf hin, dass das Objekt war == und = überlastet:

    public static bool operator ==(Region r1, Region r2)
    {
        if (object.ReferenceEquals(r1, null))
        {
            return false;
        }
        if (object.ReferenceEquals(r2, null))
        {
            return false;
        }

        return (r1.Cmr.CompareTo(r2.Cmr) == 0 && r1.Id == r2.Id);
    }


    public static bool operator !=(Region r1, Region r2)
    {
        if (object.ReferenceEquals(r1, null))
        {
            return false;
        }
        if (object.ReferenceEquals(r2, null))
        {
            return false;
        }
        return (r1.Cmr.CompareTo(r2.Cmr) != 0 || r1.Id != r2.Id);
    }
War es hilfreich?

Lösung

Ist == und / oder! = Betreiber überlastet für die Klasse der Region Objekt?

Nun, da Sie den Code für die Überlastungen geschrieben haben:

Die Überlastungen sollte wie folgt (Code aussehen wahrscheinlich von Nachrichten gemacht von Jon Skeet und Philip Rieck ):

public static bool operator ==(Region r1, Region r2)
{
    if (object.ReferenceEquals( r1, r2)) {
        // handles if both are null as well as object identity
        return true;
    }

    if ((object)r1 == null || (object)r2 == null)
    {
       return false;
    }        

    return (r1.Cmr.CompareTo(r2.Cmr) == 0 && r1.Id == r2.Id);
}

public static bool operator !=(Region r1, Region r2)
{
    return !(r1 == r2);
}

Andere Tipps

Diese Betreiber Überlastungen sind gebrochen.

Erstens ist es macht das Leben viel einfacher, wenn! = Ist nur durch Aufruf implementiert == und invertiert das Ergebnis aus.

Zum anderen, bevor die Ungültigkeit Kontrollen in == sollte es sein:

if (object.ReferenceEquals(r1, r2))
{
    return true;
}

Sowohl die Überlastungen sind falsch

 public static bool operator ==(Region r1, Region r2)
    {
        if (object.ReferenceEquals(r1, null))
        {
            return false;
        }
        if (object.ReferenceEquals(r2, null))
        {
            return false;
        }

        return (r1.Cmr.CompareTo(r2.Cmr) == 0 && r1.Id == r2.Id);
    }

Wenn R1 und R2 sind null, der erste Test ( object.ReferenceEquals (r1, null) ) gibt false zurück, auch wenn r2 auch null ist.

Versuch

//ifs expanded a bit for readability
 public static bool operator ==(Region r1, Region r2)
    {
        if( (object)r1 == null && (object)r2 == null)
        {
           return true;
        }
        if( (object)r1 == null || (object)r2 == null)
        {
           return false;
        }        
        //btw - a quick shortcut here is also object.ReferenceEquals(r1, r2)

        return (r1.Cmr.CompareTo(r2.Cmr) == 0 && r1.Id == r2.Id);
    }

Das kann manchmal passieren, wenn Sie mehrere Threads haben mit den gleichen Daten arbeiten. Wenn dies der Fall ist, können Sie eine Sperre verwenden, um sie mit ihnen aus Messing zu verhindern.

Für die Gleichstellung Vergleich eines Typs "T", diese Methoden überlasten:

int GetHashCode() //Overrides Object.GetHashCode
bool Equals(object other) //Overrides Object.Equals; would correspond to IEquatable, if such an interface existed
bool Equals(T other) //Implements IEquatable<T>; do this for each T you want to compare to
static bool operator ==(T x, T y)
static bool operator !=(T x, T y)
die typsichere IEquatable<T> Interface-Methode Equals(T other):

Ihr typspezifischen Vergleichscode sollte an einem Ort erfolgen. Wenn Sie auf eine andere Art (T2) sind zu vergleichen, implementieren IEquatable<T2> als gut, und setzen Sie das Feld Vergleichscode für diesen Typ in Equals (T2 andere).

Alle ladenen Methoden und Betreiber sollten die Gleichheit Vergleich Aufgabe zu dem wichtigsten typsichere Equals (T anderer) Instanzmethode weiterzuleiten, so dass eine saubere Abhängigkeitshierarchie beibehalten wird und strengere Garantien werden auf jeder Ebene eingeführt Redundanz und unwesentliche Komplexität zu beseitigen .

bool Equals(object other)
{
    if (other is T) //replicate this for each IEquatable<T2>, IEquatable<T3>, etc. you may implement
        return Equals( (T)other) ); //forward to IEquatable<T> implementation
    return false; //other is null or cannot be compared to this instance; therefore it is not equal
}

bool Equals(T other)
{
    if ((object)other == null) //cast to object for reference equality comparison, or use object.ReferenceEquals
        return false;
    //if ((object)other == this) //possible performance boost, ONLY if object instance is frequently compared to itself! otherwise it's just an extra useless check
        //return true;
    return field1.Equals( other.field1 ) &&
           field2.Equals( other.field2 ); //compare type fields to determine equality
}

public static bool operator ==( T x, T y )
{
    if ((object)x != null) //cast to object for reference equality comparison, or use object.ReferenceEquals
        return x.Equals( y ); //forward to type-safe Equals on non-null instance x
    if ((object)y != null)
        return false; //x was null, y is not null
    return true; //both null
}

public static bool operator !=( T x, T y )
{
    if ((object)x != null)
        return !x.Equals( y ); //forward to type-safe Equals on non-null instance x
    if ((object)y != null)
        return true; //x was null, y is not null
    return false; //both null
}

Diskussion:

Die vorstehende Umsetzung zentralisiert die typspezifische (d.h. Feld Gleichheit) gegenüber dem Ende der IEquatable<T> Implementierung für den Typen. Die == und != Betreiber haben eine parallele, aber entgegengesetzte Umsetzung. Ich ziehe diese über eine Referenz mit dem anderen, so dass es ein zusätzlichen Methodenaufruf für die abhängige ist. Wenn der != Bediener einfach wird den == Operator nennen, anstatt einen ebenso leistungs Betreiber zu bieten, dann können Sie auch nur !(obj1 == obj2) verwenden und die zusätzlichen Methodenaufruf vermeiden. Der Vergleich an sich selbst aus dem Gleichheits Operator ausgelassen und die IEquatable<T> Implementierungen, weil es 1. unnötigen Aufwand in einigen Fällen einführen können, und / oder 2. inkonsistente Leistung je nachdem, wie oft eine Instanz ist im Vergleich zu sich selbst gegen andere Instanzen .

Eine Alternative Ich mag es nicht, sollte aber erwähnt, ist diese Einstellung rückgängig zu machen, den typspezifische Gleichheit Code in dem Gleichheitsoperator Zentralisierung statt und hat die Equals Methoden ihnen verlassen. Man könnte dann die Verknüpfung von ReferenceEquals(obj1,obj2) verwenden als Referenz Gleichheit und null Gleichheit gleichzeitig zu überprüfen, wie Philip in einem frühen Beitrag erwähnt, aber diese Idee ist irreführend. Es scheint, als ob du zwei Fliegen mit einer Klappe schlagen, aber Sie eigentlich mehr Arbeit zu schaffen - nach der Bestimmung, die Objekte sind weder beide null noch die gleiche Instanz, Sie werden dann darüber hinaus müssen noch darüber, ob jede Instanz zu prüfen, ist Null. In meiner Implementierung überprüfen Sie für jede einzelne Instanz einmal null genau zu sein. Zu der Zeit, genannt die Instanz Methode Equals ist, ist es bereits ausgeschlossen, dass das erste Objekt verglichen wird, ist null, alles so zu tun übrig geblieben ist, ist zu überprüfen, ob die andere Null ist. So nach höchstens zwei Vergleiche, springen wir direkt in das Feld Prüfung, unabhängig davon, welche Methode, die wir verwenden (Equals(object),Equals(T),==,!=). Auch, wie ich bereits erwähnt, wenn Sie wirklich zu vergleichen und das Objekt sich die Mehrheit der Zeit, dann könnten Sie, dass der Check in der Equals-Methode fügen Sie einfach vor dem Tauchen in den Feldvergleiche. Der Punkt in dem Hinzufügen es zuletzt ist, dass Sie immer noch die Fluss / Abhängigkeitshierarchie ohne die Einführung eine redundante / nutzlos Kontrolle auf allen Ebenen aufrechterhalten können.

So ist es, dass diese Kontrollen sind hier nicht richtig:

public static bool operator !=(Region r1, Region r2)
{
    if (object.ReferenceEquals(r1, null))
    {
        return false;
    }
    if (object.ReferenceEquals(r2, null))
    {
        return false;
    }
...

Es gibt eine weitere Möglichkeit, dass Sie benötigen das Aktualisieren-Symbol neben dem Parameter klicken, die Sie gerade sehen. VS versucht mit der Leistung zu halten, während nicht jede Aussage / Parameter zu bewerten. Werfen Sie einen Blick, um sicherzustellen, bevor Sie Änderungen an Stellen beginnen, die nicht relevant sind.

bool comp;
if (object.IsNullOrEmpty(r1))
{
    comp = false;
}

if (object.IsNullOrEmpty(r2))
{
    comp = false;
}
return comp;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top