2009-04-25 25 views
5

Durante il tentativo di verificare a me stesso, che C# è uguale a IEnumerables è un riferimento uguale, ho trovato qualcosa di strano. Con la seguente configurazione in NUnitC# Assert.AreNotEqual versus Equals

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

questo test

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

passaggi, mentre questo test

Assert.AreNotEqual(a, b); 

no. Qualcuno può spiegare perché?

Modifica: Grazie per le risposte. Ho appena letto la documentazione per NUnit, e dice la stessa cosa, che AreEqual e AreNotEqual con test delle collezioni per l'uguaglianza di ogni elemento della collezione. Immagino di essere stato bloccato con la nozione, che AreEqual e AreNotEqual usassero semplicemente uguali.

risposta

9

La chiamata a a.Equals(b) restituisce false perché a e b non sono gli stessi oggetti (sebbene siano ovviamente identiche enumerazioni). Il metodo Equals, se non sottoposto a override, confronta automaticamente gli oggetti in base al loro riferimento, che è ciò che sta accadendo in questo caso.

Assert.AreNotEqual è un po 'più intelligente di questo. È progettato per scopi di debug, a differenza del metodo Equals, quindi confronta le sequenze fornite dalle due enumerazioni, poiché riconosce IEnumerable<T> come un tipo speciale. Dovresti anche notare che fa altre cose interessanti, come restituire true quando i due parametri sono numericamente identici ma di tipi di valore diversi (ad esempio short e long).

Spero che questo aiuti.

1

Non ho guardato il codice sorgente NUnit per vedere come i ragazzi NUnit hanno codificato AreNotEqual. Tuttavia, posso dirti come è fatto per MbUnit che ha lo stesso comportamento.

Prima in AssertNotEqual (a, b) controlla se i riferimenti sono uguali eseguendo codice come questo:

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

Nel tuo caso sta andando a fallire. Quindi controlla se gli oggetti sono di tipo IEnumerable. Se lo sono, esegui l'iterazione e confronta se gli articoli sono uguali e nello stesso ordine.

Tuttavia, in T type in IEnumerable è più complesso di string o ValueType in MbUnit AssertNotEqaual (a, b) non avrà esito negativo.

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