Assert.AreNotEqual 和 Assert.AreNotSame 有什么区别?

发布于 2024-07-13 09:58:25 字数 118 浏览 7 评论 0原文

之间有什么区别

Assert.AreNotEqual

在C#中,和

Assert.AreNotSame

In C#, what's the difference between

Assert.AreNotEqual

and

Assert.AreNotSame

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

余生共白头 2024-07-20 09:58:25

这里给出的几乎所有答案都是正确的,但可能值得举一个例子:

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);

AreNotEqualAreNotSame只是AreEqual的反转当然是相同的。

编辑:对当前接受的答案的反驳< /a>...

如果将 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);

firstNumbersecondNumber 都没有对象值,因为 int 是值类型。 AreSame 调用失败的原因是在 .NET 中,对值进行装箱每次都会创建一个新框。 (在 Java 中有时不会 - 这让我以前很困惑。)

基本上,在比较值类型时,永远不应该使用 AreSame。 当您比较引用类型时,如果您想检查相同的引用,请使用AreSame; 使用 AreEqual 检查 Equals 下的等价性。 编辑:请注意,在某些情况下,NUnit 不直接使用 Equals; 它具有对集合的内置支持,其中集合中的元素被测试是否相等。

答案中的主张是:

使用上面的示例更改
int 到 string、AreSame 和 AreEqual
将返回相同的值。

完全取决于变量的初始化方式。 如果他们使用字符串文字,那么是的,实习会解决这个问题。 但是,如果您使用:,

string firstString = 1.ToString();
string secondString = 1.ToString();

AreSameAreEqual 几乎肯定不会返回相同的值。

至于:

一般经验法则是使用
值类型上的 AreEqual 和 AreSame 上的
参考类型。

我几乎从不想要检查参考身份。 它对我来说很少有用。 我想检查等价,这就是AreEqual 检查的内容。 (我并不是说 AreSame 不应该存在 - 这是一个有用的方法,只是比 AreEqual 少得多。)

Almost all the answers given here are correct, but it's probably worth giving an example:

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 and AreNotSame are just inversions of AreEqual and AreSame of course.

EDIT: A rebuttal to the currently accepted answer...

If you use Assert.AreSame with value types, they are boxed. In other words, it's equivalent to doing:

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);

Neither firstNumber nor secondNumber has an object value, because int is a value type. The reason the AreSame call will fail is because in .NET, boxing a value creates a new box each time. (In Java it sometimes doesn't - this has caught me out before.)

Basically you should never use AreSame when comparing value types. When you're comparing reference types, use AreSame if you want to check for identical references; use AreEqual to check for equivalence under Equals. EDIT: Note that there are situations where NUnit doesn't just use Equals directly; it has built-in support for collections, where the elements in the collections are tested for equality.

The claim in the answer that:

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

过期情话 2024-07-20 09:58:25

两个事物可以是相同的,但可以是不同的对象。 AreNotEqual 通过相等测试检查对象,而 AreNotSame 检查它们是否不是同一个确切的对象。

很明显,为什么我们想要测试 AreNotEqual(我们关心正在测试的值); 不一样呢? 当您传递引用并希望确保在改组完成后两个引用仍然是同一个对象时,就会发现此功能在测试中的用处。

在现实世界中,我们使用大量缓存对象来减少数据库的往返次数。 将对象移交给缓存系统后,我们的单元测试确保在某些情况下我们返回相同的对象(缓存有效),而在其他情况下我们返回一个新鲜对象(缓存已作废)。 请注意,在这种情况下,AreNotEqual 不一定足够。 如果对象在数据库中具有新的时间戳,但数据还没有“足够不同”而无法通过相等性测试,则 AreNotEqual 不会注意到我们刷新了对象

Two things can be equal, but different objects. AreNotEqual checks the objects values via the equality test, while AreNotSame checks that they are not the same exact object.

It is obvious why we would want to test that things AreNotEqual (we care about the values being tested); what about AreNotSame? The usefulness of this in testing is found when you have passed references around and want to make sure that after your shuffling is done that two references are still the same object.

In a real world case, we use a lot of caching objects to mitigate round trips to the database. After an object has been handed off to the cache system, our unit tests ensure that in some cases we get back the same object (cache was valid) and in other cases we get back a fresh object (cache was invalidated). Note that AreNotEqual would not necessary suffice in this case. If the object had a new timestamp in the database, yet the data was not "different enough" to fail an equality test, AreNotEqual wouldn't notice that we refreshed the object.

笑叹一世浮沉 2024-07-20 09:58:25

AreNotSame 进行参考比较,而 AreNotEqual 则相等比较。

AreNotSame does reference comparison, whereas AreNotEqual does an equality comparison.

黑色毁心梦 2024-07-20 09:58:25

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);

Assert.AreNotEqual asserts that two values are not equal to each other.

Assert.AreNotSame asserts that two variables do not point to the same object.

Example 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);

Example 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);
泪眸﹌ 2024-07-20 09:58:25

AreNotSame 使用引用相等 (object.ReferenceEquals) - 即它们是否是对象的相同实际实例; AreNotEqual 使用概念相等 (.Equals) - 即它们被认为相等。

AreNotSame uses reference equality (object.ReferenceEquals) - i.e. are they the same actual instance of an object; AreNotEqual uses conceptual equality (.Equals) - i.e. are they considered equal.

江湖彼岸 2024-07-20 09:58:25

难道 AreNotEqual 检查两个对象在 Equals() 方法中不相等的情况,而 AreNotSame 检查两个对象引用不同的情况。 因此,如果 x 和 y 是两个在 Equals() 方面相等但已单独分配的对象,则 AreNotEqual() 将触发失败的断言,而另一个则不会。

Isn't it so that AreNotEqual checks for the case where two objects are not equal in terms of Equals() method, whereas AreNotSame checks for the case where the two object references are not the same. So if x and y are two objects which are equal in terms of Equals() but have been separately allocated, AreNotEqual() would trigger failing assertion but the other not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文