Um zwei Werte auf Gleichheit zu prüfen stehen in C# mehrere Möglichkeiten zur Verfügung. In diesem Artikel möchte ich die drei am häufigsten verwendeten Alternativen ReferenceEquals, Equals und den == Operator vorstellen und deren kleine aber entscheidende Unterschiede erläutern.
ReferenceEquals
Diese Funktion dient zum Vergleichen von zwei Referenztypen. Sie vergleicht ob es sich bei den beiden Objekten um dieselbe Instanz handelt und gibt in diesem Fall true zurück. Es wird auch true zurückgegeben wenn beide Werte null sind. Da Referenztypen verglichen werden, wird bei der Übergabe von Werttypen immer false zurückgegeben.
Der nachfolgende Quellcode zeigt entsprechende Beispiele. Das Ergebnis der Funktionen ist direkt im Quellcode als Kommentar angegeben.
int intValueA = 1; int intValueB = 1; int intValueC = 2; double doubleValue = 1.0; string strValueA = "abc"; string strValueB = "abc"; string strValueC = "def"; StringBuilder builderValueA = new StringBuilder("abc"); StringBuilder builderValueB = builderValueA; StringBuilder builderValueC = new StringBuilder("abc"); Console.WriteLine("int/int: " + ReferenceEquals(intValueA, intValueB)); //false Console.WriteLine("int/int: " + ReferenceEquals(intValueA, intValueC)); //false Console.WriteLine("int/double: " + ReferenceEquals(intValueA, doubleValue)); //false Console.WriteLine("str/str: " + ReferenceEquals(strValueA, strValueB)); //true Console.WriteLine("str/str: " + ReferenceEquals(strValueA, strValueC)); //false Console.WriteLine("builder/builder: " + ReferenceEquals(builderValueA, builderValueB)); //true Console.WriteLine("builder/builder: " + ReferenceEquals(builderValueA, builderValueC)); //false
Interessant in dem Beispiel ist, das strValueA und strValueB die gleiche Instanz eines Objektes repräsentieren. Dies liegt an der .NET spezifischen Verwaltung von Zeichenketten.
Equals
Die Funktion dient zum Vergleichen von zwei Referenztypen oder Werttypen. Bei Referenztypen verhält sich die Funktion analog zu ReferenceEquals und prüft ob es sich bei den beiden Objekten um dieselbe Instanz handelt. Bei Werttypen hingegen wird der tatsächliche Wert verglichen.
int intValueA = 1; int intValueB = 1; int intValueC = 2; double doubleValue = 1.0; string strValueA = "abc"; string strValueB = "abc"; string strValueC = "def"; StringBuilder builderValueA = new StringBuilder("abc"); StringBuilder builderValueB = builderValueA; StringBuilder builderValueC = new StringBuilder("abc"); Console.WriteLine("int/int: " + Equals(intValueA, intValueB)); //true Console.WriteLine("int/int: " + Equals(intValueA, intValueC)); //false Console.WriteLine("int/double: " + Equals(intValueA, doubleValue)); //false Console.WriteLine("str/str: " + Equals(strValueA, strValueB)); //true Console.WriteLine("str/str: " + Equals(strValueA, strValueC)); //false Console.WriteLine("builder/builder: " + Equals(builderValueA, builderValueB)); //true Console.WriteLine("builder/builder: " + Equals(builderValueA, builderValueC)); //false
In Zeile 14 ist zu sehen dass nun auch der Vergleich der Werte bei Werttypen erfolgt.
== Operator
Mit Hilfe des == Operators lassen sich ebenfalls zwei Werte vergleichen. Dabei verhält sich der == Operator wie die Equals Funktion und vergleicht die Instanzen bei Referenztypen und die tatsächlichen Werte bei Werttypen. Im Gegensatz zur Equals Funktion können aber auch Werttypen verglichen Werten die nicht vom gleichen Typ sind.
In Zeile 17 des Beispiels wird ein integer Wert mit einem double Wert verglichen. Bei Verwendung des == Operators wird dabei true zurückgegeben.
int intValueA = 1; int intValueB = 1; int intValueC = 2; double doubleValue = 1.0; string strValueA = "abc"; string strValueB = "abc"; string strValueC = "def"; StringBuilder builderValueA = new StringBuilder("abc"); StringBuilder builderValueB = builderValueA; StringBuilder builderValueC = new StringBuilder("abc"); Console.WriteLine("int/int: " + (intValueA == intValueB)); //true Console.WriteLine("int/int: " + (intValueA == intValueC)); //false Console.WriteLine("int/double: " + (intValueA == doubleValue)); //true Console.WriteLine("str/str: " + (strValueA == strValueB)); //true Console.WriteLine("str/str: " + (strValueA == strValueC)); //false Console.WriteLine("builder/builder: " + (builderValueA == builderValueB)); //true Console.WriteLine("builder/builder: " + (builderValueA == builderValueC)); //false
Fazit
Anhand der Beispiele ist zu sehen dass sich die drei Alternativen zum Vergleich von zwei Werten unterscheiden. Je nach Anwendungsfall muss daher d