Ответ 1
Почти все приведенные здесь ответы верны, но, вероятно, стоит привести пример:
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
, конечно.
EDIT: опровержение принятого в настоящее время ответа...
Если вы используете 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 not intended for use with value types
Assert.AreSame(boxedFirstNumber, boxedSecondNumber);
Ни firstNumber
, ни secondNumber
не имеет значения объекта, потому что int
- тип значения. Причина, по которой вызов AreSame
завершится неудачей, заключается в том, что в .NET бокс-значение каждый раз создает новый ящик. (В Java иногда это не так - это меня уже укусило.)
В основном вы никогда не должны использовать AreSame
при сравнении типов значений. Когда вы сравниваете типы ссылок, используйте AreSame
, если вы хотите проверить идентичные ссылки; используйте AreEqual
для проверки эквивалентности в Equals
. EDIT: Обратите внимание, что есть ситуации, когда NUnit не просто использует Equals
напрямую; он имеет встроенную поддержку коллекций, где элементы в коллекциях проверяются на равенство.
Требование в ответ, что:
Используя приведенный выше пример, изменив int to string, AreSame и AreEqual вернет то же значение.
полностью зависит от того, как инициализируются переменные. Если они используют строковые литералы, то, тем не менее, интернинг позаботится об этом. Если, однако, вы используете:
string firstString = 1.ToString();
string secondString = 1.ToString();
то AreSame и AreEqual почти наверняка не вернут одно и то же значение.
Что касается:
Общим правилом является использование AreEqual по типам значений и AreSame on ссылочные типы.
Я почти никогда не хочу проверять ссылочную идентификацию. Мне это редко бывает полезно. Я хочу проверить эквивалентность, что проверяет AreEqual
. (Я не говорю, что AreSame
не должно быть там - это полезный метод, гораздо реже, чем AreEqual
.)