C#中包含子类集合的类的Equals方法重写


最近的项目中,对于单元测试,我们使用NMock来模拟测试方法中依赖的方法的行为。我们在定义模拟方法的参数值和返回值时遇到了问题。当参数或返回值为一个对象时,我们必须重写它的Equals方法来使模拟值与实际的值匹配。

因此我会为每个实体类重写Equals和GetHashCode方法。

我们有这样一个类:

  1. public class ShippingRequest  
  2. {  
  3.     IEnumerable<string> ResourceIds;  
  4.     string Receiver;  
  5.     string Comment;  
  6. }  

它的Equals方法中会对ResourceIds、Receiver和Comment的值作比较,如果全部相同则返回true。

ResourceIds实际上是我们需要邮寄的一组设备的Id号,因此我们并不在意它们的顺序,只要两个对象中包含了一组同样的Id号即可确定它们的ResourceIds是相等的。

怎么对集合类型的ResourceIds作比较呢?
自然我们可以对集合中的元素做一一比较查看两组集合中是不是包含了相同的元素。

但是如果使用LINQ,我们可以用非常简单的方式。

list2.Except(list1);//返回在list2中但不在list1中的元素  

因此我们可以将ShippingRequest类的Equals方法写成这样:

  1. public override bool Equals(object o)  
  2. {  
  3.     if (o == null || !this.GetType().Equals(o.GetType()))  
  4.     {  
  5.         return false;  
  6.     }  
  7.     if(this == o)  
  8.     {  
  9.         return true;  
  10.     }  
  11.     var shippingRequest = o as ShippingRequest ;  
  12.     if(this.ResourceIds.Except(shippingRequest.ResourceIds).Count()==0 &&  
  13.         shippingRequest.ResourceIds.Except(this.ResourceIds).Count()==0 &&  
  14.         this.Receiver.Equals(shippingRequest .Receiver) &&  
  15.         this.Comment.Equals(shippingRequest .Comment))  
  16.     {  
  17.         return true;  
  18.     }  
  19.     return false;  
  20. }  

然后我们只需重写ShippingRequest类的GetHashCode方法就完成了整个类。

这里所说的集合类型可以是IEnumerable,或者实现它的任意集合类。而集合中的类型也可以是任意类型,当然如果是自定义的类,我们首先需要正确的重写该自定义类的Equals方法。

相关内容