Почти все ответы, приведенные здесь, верны, но, вероятно, стоит привести пример:
public static string GetSecondWord(string text)
{
// Yes, an appalling implementation...
return text.Split(' ')[1];
}
string expected = "world";
string actual = GetSecondWord("hello world");
// Good: the two strings should be *equal* as they have the same contents
Assert.AreEqual(expected, actual);
// Bad: the two string *references* won't be the same
Assert.AreSame(expected, actual);
AreNotEqual
и AreNotSame
- это, конечно, инверсии AreEqual
и AreSame
.
РЕДАКТИРОВАТЬ: опровержение в настоящее время принятый ответ ...
Если вы используете Assert.AreSame
с типами значений, они помещаются в квадрат. Другими словами, это эквивалентно выполнению:
int firstNumber = 1;
int secondNumber = 1;
object boxedFirstNumber = firstNumber;
object boxedSecondNumber = secondNumber;
// There are overloads for AreEqual for various value types
// (assuming NUnit here)
Assert.AreEqual(firstNumber, secondNumber);
// ... but not for AreSame, as it's not intended for use with value types
Assert.AreSame(boxedFirstNumber, boxedSecondNumber);
Ни firstNumber
, ни secondNumber
не имеют значения объекта, поскольку int
является типом значения. Причина, по которой вызов AreSame
не удастся, заключается в том, что в .NET при упаковке значения каждый раз создается новое поле. (В Java это иногда не так - меня это уже поразило.)
Как правило, никогда не следует использовать AreSame
при сравнении типов значений. Когда вы сравниваете ссылки типов, используйте AreSame
, если вы хотите проверить идентичные ссылки; используйте AreEqual
, чтобы проверить эквивалентность в Equals
. РЕДАКТИРОВАТЬ: Обратите внимание, что бывают ситуации, когда NUnit не просто использует Equals
напрямую; в него встроена поддержка коллекций, где элементы в коллекциях проверяются на равенство.
Претензия в ответе:
Используя приведенный выше пример изменения
int в строку, AreSame и AreEqual
вернет то же значение.
полностью зависит от того, как инициализируются переменные. Если они используют строковые литералы, тогда интернирование позаботится об этом. Однако, если вы используете:
string firstString = 1.ToString();
string secondString = 1.ToString();
тогда AreSame и AreEqual почти наверняка не вернут одно и то же значение.
Что касается:
Общее правило - использовать
AreEqual для типов значений и AreSame для
ссылочные типы.
Я почти никогда хочу проверить идентификационные данные. Это редко полезно для меня. Я хочу проверить эквивалентность , что AreEqual
проверяет. (Я не говорю, что AreSame
не должно быть там - это полезный метод, просто гораздо реже, чем AreEqual
.)