在 C# 中,有什么区别
Assert.AreNotEqual
和
Assert.AreNotSame
这里给出的几乎所有答案都是正确的,但可能值得举一个例子:
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
直接使用;它具有对集合的内置支持,其中集合中的元素被测试是否相等。
答案中的主张是:
Using the example above changing the int to string, AreSame and AreEqual will return the same value.
entirely depends on how the variables are initialized. If they use string literals, then yes, interning will take care of that. If, however, you use:
string firstString = 1.ToString();
string secondString = 1.ToString();
then AreSame
and AreEqual
will almost certainly not return the same value.
As for:
The general rule of thumb is to use AreEqual on value types and AreSame on reference types.
I almost never want to check for reference identity. It's rarely useful to me. I want to check for equivalence which is what AreEqual
checks for. (I'm not saying that AreSame
shouldn't be there - it's a useful method, just far more rarely than AreEqual
.)
两件事可以相等,但对象不同。AreNotEqual 通过相等测试检查对象值,而 AreNotSame 检查它们是否不是完全相同的对象。
很明显我们为什么要测试 AreNotEqual 的东西(我们关心被测试的值);AreNotSame 怎么样?当您传递引用并希望确保在完成混洗后两个引用仍然是同一个对象时,就会发现它在测试中的用处。
在现实世界的案例中,我们使用大量缓存对象来减少到数据库的往返次数。在将对象移交给缓存系统后,我们的单元测试确保在某些情况下我们会返回相同的对象(缓存是有效的),而在其他情况下我们会返回一个新的对象(缓存无效)。请注意,在这种情况下,AreNotEqual 是不够的。如果对象在数据库中有一个新的时间戳,但数据没有“足够不同”而无法通过相等性测试,则 AreNotEqual 不会注意到我们刷新了对象。
AreNotSame进行引用比较,而AreNotEqual进行相等比较。
Assert.AreNotEqual 断言两个值不相等。
Assert.AreNotSame 断言两个变量不指向同一个对象。
示例 1:
诠释 i = 1; 诠释 j = 我; // 值相等: 断言.AreEqual(i, j); // 两个值类型*不*代表同一个对象: 断言.AreNotSame(i, j);
示例 2:
字符串 s = "A"; 字符串 t = s; // 值相等: 断言.AreEqual(s, t); // 引用类型*可以*指向同一个对象: 断言.AreSame(s, t);
AreNotSame 使用引用相等 ( object.ReferenceEquals
) - 即它们是对象的相同实际实例吗?AreNotEqual 使用概念上的相等 ( .Equals
) - 即它们是否被视为相等。
不是说 AreNotEqual 根据 Equals() 方法检查两个对象不相等的情况,而 AreNotSame 则检查两个对象引用不相同的情况。因此,如果 x 和 y 是两个在 Equals() 方面相等但已分别分配的对象,则 AreNotEqual() 将触发断言失败,而另一个则不会。