2009-04-25 21 views
5

Al tratar de verificarme a mí mismo, que C# Igual para IEnumerables es una referencia igual, encontré algo extraño. Con la siguiente configuración en NUnitC# Assert.AreNotEqual versus Igual

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

esta prueba

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

pases, mientras que esta prueba

Assert.AreNotEqual(a, b); 

no. ¿Alguien puede explicar por qué?

Editar: Gracias por las respuestas. Acabo de leer la documentación para NUnit, y dice lo mismo, que AreEqual y AreNotEqual con colecciones prueban la igualdad de cada elemento de la colección. Creo que estaba atrapado con la noción de que AreEqual y AreNotEqual simplemente usaban Iguales.

Respuesta

9

La llamada a a.Equals(b) devuelve false porque a y b no son los mismos objetos (aunque son, por supuesto, enumeraciones idénticas). El método Equals, a menos que se modifique, compara automáticamente objetos por referencia, que es lo que está sucediendo en este caso.

Assert.AreNotEqual es un poco más inteligente que esto. Está diseñado para depuración, a diferencia del método Equals, por lo que de hecho compara las secuencias producidas por las dos enumeraciones, ya que reconoce IEnumerable<T> como un tipo especial. También debe observar que hace otras cosas interesantes, como devolver true cuando los dos parámetros son numéricamente idénticos pero de diferentes tipos de valores (por ejemplo, short y long).

Espero que ayude.

1

No miré el código fuente de NUnit para ver cómo los chicos de NUnit codificaron AreNotEqual. Sin embargo, puedo decirte cómo se hace para MbUnit que tiene el mismo comportamiento.

Primero en AssertNotEqual (a, b) comprueba si las referencias son iguales mediante la ejecución de código como este:

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

En su caso va a fallar. A continuación, comprueba si los objetos son de tipo IEnumerable. Si lo son, repítelos y compare si los artículos son iguales y están en el mismo orden.

Sin embargo, en T escriba IEnumerable es más complejo que string o ValueType en MbUnit AssertNotEqaual (a, b) no fallará.

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