Dank des Feedbacks in den beiden vorherigen Artikeln, und im speziellen die Kommentare von winSharp93 im vorangegangenen Beitrag, habe ich nun endlich eine saubere Lösung gefunden. Manchmal muss man halt mit der Nase darauf gestoßen werden. Object.ReferenceEquals ist der perfekte Weg um die Instanzen zweier Objekte zu vergleichen; sagt ja auch der Name der Methode.
Der Fehler den ich von Anfang an beging, war schlicht und einfach das Vergessen der Instanz Prüfung, nach dem ich die Equals-Methoden sowie die Operatoren == und != überschrieben hatte. Man kann nun mal nicht den Inhalt zweier Klassen vergleichen, wenn eine oder beide einen null-Verweis besitzen. Also muss in der Methode Equals(T other) als erstes eine Prüfung gegen null des other-Parameters her. Sollte hier true zurückgegeben werden, wird die aktuelle Instanz, also this, ebenfalls gegen null geprüft. Es könnten ja zwei null-Instanzen des Typs miteinander verglichen werden, was durchaus legitim ist. In diesem Fall muss die Methode Equals true zurück geben, da null == null nun mal true ergibt. Als nächstes wird noch einmal die aktuelle Instanz separat gegen null geprüft, denn sie könnte null sein und der other-Parameter eine erzeugte Instanz enthalten. Als letzten werden dann noch die Inhalte der Eigenschaften im einzelnen verglichen.
namespace ClassTests
{
using System;
public sealed class Test : IComparable<Test>
{
public int Number
{ get; set; }
public string Text
{ get; set; }
public Test()
{
}
public int CompareTo(Test other)
{
return this.Number.CompareTo(other.Number);
}
public static bool operator ==(Test t1, Test t2)
{
return object.Equals(t1, t2);
}
public static bool operator !=(Test t1, Test t2)
{
return !object.Equals(t1, t2);
}
public static bool operator >(Test t1, Test t2)
{
return (t1.CompareTo(t2) > 0);
}
public static bool operator <(Test t1, Test t2)
{
return (t1.CompareTo(t2) < 0);
}
public override bool Equals(object obj)
{
return this.Equals(obj as Test);
}
public bool Equals(Test other)
{
if (object.ReferenceEquals(other, null))
{
if (object.ReferenceEquals(this, null))
{
return true;
}
return false;
}
if (object.ReferenceEquals(this, null))
{
return false;
}
if (this.Number.CompareTo(other.Number) != 0)
{
return false;
}
if (string.Compare(this.Text, other.Text, StringComparison.Ordinal) != 0)
{
return false;
}
return true;
}
}
}Mit dieser Implementierung ist das Verhalten nun endlich so, wie es von Anfang an sein sollte; Instanz Prüfung, Inhaltsprüfung und Größenvergleich.
Ich möchte mich hier auch noch einmal bei allen Kommentierenden, besonders bei winSharp93, bedanken. Ohne euch würde ich wahrscheinlich noch immer grübeln.
Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war, bitte "kicken" sie ihn.
-implementieren-und-null-die-Losung.aspx)