Assert.AreEqual 不在 IEnumerable 实现上使用我的 .Equals 覆盖 [英] Assert.AreEqual does not use my .Equals overrides on an IEnumerable implementation

查看:23
本文介绍了Assert.AreEqual 不在 IEnumerable 实现上使用我的 .Equals 覆盖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 PagedModel 类,它实现了 IEnumerable 只返回 ModelData,忽略分页数据.我还覆盖了 Equals 和 GetHashCode,以允许通过 ModelData、PageNumber、TotalPages 和 PageSize 比较两个 PagedModel 对象.

I have a PagedModel class which implements IEnumerable to just return the ModelData, ignoring the paging data. I have also overridden Equals and GetHashCode to allow comparing two PagedModel objects by their ModelData, PageNumber, and TotalPages, and PageSize.

问题来了

Dim p1 As New PagedModel() With {
    .PageNumber = 1,
    .PageSize = 10,
    .TotalPages = 10,
    .ModelData = GetModelData()
}

Dim p2 As New PagedModel() With {
    .PageNumber = 1,
    .PageSize = 10,
    .TotalPages = 10,
    .ModelData = GetModelData()
}

p1.Equals(p2) =====> True
Assert.AreEqual(p1, p2) ======> False!

看起来 NUnit 正在调用它的内部 EnumerableEqual 方法来比较我的 PagedModel,而不是使用我提供的 Equals 方法!有什么方法可以覆盖这种行为,或者我必须编写自定义断言.

It looks like NUnit is calling it's internal EnumerableEqual method to compare my PagedModel's instead of using the Equals methods I provided! Is there any way to override this behavior, or do I have to write a custom Assertion.

推荐答案

做你想做的:我建议不要这样做,但如果你真的不喜欢 NUnit 的行为并想要自定义断言您可以提供自己的 EqualityComparer.

Doing what you are asking: I would advise against it but if you really don't like NUnit's behaviour and want to customize the assertion you can provide your own EqualityComparer.

Assert.That(p1, Is.EqualTo(p2).Using(myCustomEqualityComparer));

您应该做什么(简短回答):您需要 GetHashCode 和等于 ModelData 而不是 PagedModel,因为您使用 PagedModel 作为集合并使用 ModelData 作为元素.

你应该做什么(长答案):而不是在 PagedModel 上覆盖 Equals(object) 你需要在 ModelData 上实现 IEquatable,其中 T 是IEnumerable 的类型参数,以及覆盖 GetHashCode().这两种方法是 .Net 中的所有 IEnumerable 方法在使用 默认相等比较器(您没有指定自己的 IEqualityComparer).

What you should be doing (short answer): You need GetHashCode and equals on ModelData instead of PagedModel since you are using PagedModel as the collection and ModelData as the elements.

What you should be doing (Long answer): Instead of overriding Equals(object) on PagedModel you need to implement IEquatable<T> on ModelData, where T is the type parameter to the IEnumerable, as well as override GetHashCode(). These two methods are what all IEnumerable methods in .Net use to determine equality (for operations such as Union, Distinct etc) when using the Default Equality Comparer (you don't specify your own IEqualityComparer).

[Default Equality Comparer] 检查类型 T 是否实现 System.IEquatable 接口,如果是,则返回使用该实现的 EqualityComparer.否则,它返回一个 EqualityComparer,它使用 T 提供的 Object.Equals 和 Object.GetHashCode 的覆盖.

The [Default Equality Comparer] checks whether type T implements the System.IEquatable interface and, if so, returns an EqualityComparer that uses that implementation. Otherwise, it returns an EqualityComparer that uses the overrides of Object.Equals and Object.GetHashCode provided by T.


为了正确运行,GetHashCode 需要为所有对 .Equals(T) 返回 true 的对象返回相同的结果.反过来不一定正确 - GetHashCode 可以为不相等的对象返回冲突.更多信息在这里 -参见 Marc Gravel 接受的答案.我还发现在该答案中使用素数实现 GetHashCode 非常有用.


To function correctly, GetHashCode needs to return the same results for all objects that return true for .Equals(T). The reverse is not necessarily true - GetHashCode can return collisions for objects that are not equal. More information here - see Marc Gravel's accepted answer. I have also found the implementation of GetHashCode in that answer using primes very useful.

这篇关于Assert.AreEqual 不在 IEnumerable 实现上使用我的 .Equals 覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆