在C#中,有什么区别
Assert.AreNotEqual
和
Assert.AreNotSame
Jon Skeet.. 82
这里给出的几乎所有答案都是正确的,但它可能值得举个例子:
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更改为string,AreSame和AreEqual将返回相同的值.
完全取决于变量的初始化方式.如果他们使用字符串文字,那么,实习将负责这一点.但是,如果您使用:
string firstString = 1.ToString(); string secondString = 1.ToString();
然后AreSame和AreEqual几乎肯定不会返回相同的值.
至于:
一般的经验法则是在值类型上使用AreEqual,在引用类型上使用AreSame.
我几乎从不想检查参考身份.这对我来说很少有用.我想检查等价是什么AreEqual
检查.(我不是说那AreSame
不应该存在 - 这是一种有用的方法,远比它少得多AreEqual
.)
这里给出的几乎所有答案都是正确的,但它可能值得举个例子:
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更改为string,AreSame和AreEqual将返回相同的值.
完全取决于变量的初始化方式.如果他们使用字符串文字,那么,实习将负责这一点.但是,如果您使用:
string firstString = 1.ToString(); string secondString = 1.ToString();
然后AreSame和AreEqual几乎肯定不会返回相同的值.
至于:
一般的经验法则是在值类型上使用AreEqual,在引用类型上使用AreSame.
我几乎从不想检查参考身份.这对我来说很少有用.我想检查等价是什么AreEqual
检查.(我不是说那AreSame
不应该存在 - 这是一种有用的方法,远比它少得多AreEqual
.)
两件事可以是平等的,但不同的对象.AreNotEqual 通过相等性测试检查对象值,而AreNotSame检查它们不是完全相同的对象.
很明显,为什么我们要测试AreNotEqual(我们关心被测试的值); 怎么样AreNotSame?当您传递了引用并希望确保在完成两次引用之后仍然是同一个对象时,可以找到它在测试中的用处.
在现实世界中,我们使用大量缓存对象来减少到数据库的往返.在将对象传递给缓存系统之后,我们的单元测试确保在某些情况下我们返回相同的对象(缓存有效),而在其他情况下,我们返回一个新对象(缓存无效).请注意,在这种情况下,AreNotEqual不一定足够.如果对象在数据库中有一个新的时间戳,但数据没有"足够差异"以使相等测试失败,AreNotEqual将不会注意到我们刷新了对象.
AreNotSame确实引用了比较,而AreNotEqual进行了相等比较.
Assert.AreNotEqual断言两个值彼此不相等.
Assert.AreNotSame断言两个变量不指向同一个对象.
例1:
int i = 1; int j = i; // The values are equal: Assert.AreEqual(i, j); // Two value types do *not* represent the same object: Assert.AreNotSame(i, j);
例2:
string s = "A"; string t = s; // The values are equal: Assert.AreEqual(s, t); // Reference types *can* point to the same object: Assert.AreSame(s, t);
AreNotSame使用引用相等(object.ReferenceEquals
) - 即它们是对象的实际实例; AreNotEqual使用概念相等(.Equals
) - 即它们被认为是相等的.