C # Assert.AreNotEqual против равных - PullRequest
5 голосов
/ 26 апреля 2009

Пытаясь доказать себе, что C # Equals для IEnumerables - это ссылка equals, я обнаружил нечто странное. Со следующей настройкой в ​​NUnit

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

этот тест

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

проходит, а этот тест

Assert.AreNotEqual(a, b);

нет. Кто-нибудь может объяснить, почему?

Редактировать: Спасибо за ответы. Я только что прочитал документацию по NUnit, и там написано то же самое, что AreEqual и AreNotEqual с коллекциями проверяют равенство каждого элемента коллекции. Я предполагаю, что застрял с мыслью, что AreEqual и AreNotEqual просто использовали простые Equals.

Ответы [ 2 ]

9 голосов
/ 26 апреля 2009

Вызов a.Equals(b) возвращает false, потому что a и b не являются одинаковыми объектами (хотя они, конечно, являются идентичными перечислениями). Метод Equals, если он не переопределен, автоматически сравнивает объекты по их ссылке, что и происходит в этом случае.

Assert.AreNotEqual немного умнее, чем это. Он разработан для целей отладки, в отличие от метода Equals, поэтому фактически сравнивает последовательности, полученные в результате двух перечислений, поскольку он распознает IEnumerable<T> как специальный тип. Вы также должны заметить, что он делает другие интересные вещи, например, возвращает true, когда два параметра численно идентичны, но имеют разные типы значений (например, short и long).

Надеюсь, это поможет.

1 голос
/ 26 апреля 2009

Я не смотрел исходный код NUnit, чтобы увидеть, как ребята из NUnit закодировали AreNotEqual. Однако я могу рассказать вам, как это делается для MbUnit с таким же поведением.

Сначала в AssertNotEqual (a, b) проверяется, равны ли ссылки, выполняя код следующим образом:

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

В вашем случае это не удастся. Затем он проверяет, являются ли объекты типом IEnumerable. Если они есть, выполните итерацию по ним и сравните, если элементы одинаковы и в том же порядке.

Однако в T типе в IEnumerable сложнее, чем string или ValueType в MbUnit.

    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
...