2009-04-25 7 views
5

Beim Versuch, mir selbst zu überprüfen, dass C# gleich für IEnumerables ist eine Referenz gleich ist, fand ich etwas seltsam. Mit dem folgenden Setup in NUnitC# Assert.AreNotEqual im Vergleich zu Equals

var a = (IEnumerable<string>)(new[] { "one", "two" }); 
var b = (IEnumerable<string>)(new[] { "one", "two" }); 

dieser Test

Assert.IsFalse(a.Equals(b)); 

Pässe, während dieses Tests

Assert.AreNotEqual(a, b); 

nicht. Kann jemand erklären warum?

Edit: Danke für die Antworten. Ich lese gerade die Dokumentation für NUnit, und es sagt dasselbe, dass AreEqual und AreNotEqual mit Sammlungen auf Gleichheit jedes Elementes der Sammlung prüfen. Ich glaube, ich war fest davon überzeugt, dass AreEqual und AreNotEqual einfach nur Equals verwendeten.

Antwort

9

Der Aufruf an gibt false zurück, da a und b nicht die gleichen Objekte sind (obwohl sie natürlich identische Aufzählungen sind). Die Equals-Methode vergleicht, sofern sie nicht überschrieben wird, Objekte automatisch anhand ihrer Referenz, was in diesem Fall der Fall ist.

Assert.AreNotEqual ist ein bisschen schlauer als das. Es ist im Gegensatz zur Equals-Methode für Debugging-Zwecke ausgelegt, vergleicht also die von den beiden Enumerationen gelieferten Sequenzen, da es IEnumerable<T> als speziellen Typ erkennt. Sie sollten auch feststellen, dass es andere interessante Dinge tut, wie true zurückkehrt, wenn die beiden Parameter numerisch identisch sind, aber von verschiedenen Werttypen (z short und long).

Hoffe, dass hilft.

1

Ich habe NUnit-Quellcode nicht angesehen, um zu sehen, wie NUnit-Typen AreNotEqual codierten. Allerdings kann ich Ihnen sagen, wie es für MbUnit gemacht wird, das das gleiche Verhalten hat.

Zuerst in AssertNotEqual (a, b) prüft, ob Referenzen durch Ausführen Code wie folgt gleich sind:

if (Object.ReferenceEquals(left, right)) 
     return true; 

In Ihrem Fall, es wird scheitern. Als Nächstes wird geprüft, ob die Objekte vom Typ IEnumerable sind. Wenn dies der Fall ist, durchlaufen Sie sie und vergleichen Sie, ob die Elemente gleich und in der gleichen Reihenfolge sind.

jedoch in T-Typ in IEnumerable ist komplexer als Zeichenkette oder Valuetype in MbUnit AssertNotEqaual (a, b) nicht fehlschlagen.

var a = (IEnumerable<StringBuilder>)(new[] { new StringBuilder("one"), new StringBuilder("two") }); 
    var b = (IEnumerable<StringBuilder>)(new[] { new StringBuilder("one"), new StringBuilder("two") }); 

    Assert.IsFalse(a.Equals(b)); // Success 
    Assert.AreNotEqual(a, b);  // Success 
Verwandte Themen