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

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

问题描述

我有一个实现IEnumerable的PagedModel类,只返回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上覆盖等于(对象),需要在ModelData上实现 IEquatable< T> ,其中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比较器]检查类型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天全站免登陆