【C#】如何比较两个对象是否相等(重写Equals方法)

问题: 写单元测试时,需要对比两个对象是否相等,如果使用Assert.AreEqual(mockclass1, class1)永远无法通过。

原因: 这里使用了object默认的Equals方法,必须要引用同一个对象,才会返回true 。默认的Equals方法实现的只是同一性(identity),而不是相等性(equality)

合理的Equals方法本应该这样实现:

  1. 如果obj实参为空,就返回false,因为调用的是非静态Equals方法,this标识的当前对象肯定不为空;
  2. 如果thisobj实参引用同一个对象,就返回true。在比较大量字段时,这一步有助于提升性能;
  3. 如果thisobj实参引用不同类型的对象,就返回false
  4. 针对类型定义的每个实例字段,将this对象中的值与obj对象中的值进行比较,任何字段不相等,返回false
  5. 调用基类的Equals方法比较它定义的任何字段,返回基类的Equals结果。

由于Microsoft并没有这样实现Equals,所以需要针对不同的对象重写Equals方法,为了仍然能测试同一性,Object提供了静态方法ReferenceEquals

同一性

检查同一性(看两个引用是否指向同一个对象),务必调用 ReferenceEquals,不应该使用==操作符,因为类型可能重载了操作符。

相等性

重写Equals方法时,除了上文所讲的,还应该做下面几件事:

  • 让类型实现System.IEquatable<T>接口的Equals方法。
    这个泛型接口允许定义类型安全的Equals方法,在重写的Equals(object obj)方法中调用这个类型安全的方法。
  • 重载==!=操作符方法。
  • 如果需要排序而比较类型的实例,还应该实现System.IComparableCompareTo方法以及各种比较操作符。
  • 重写类型的GetHashCode方法。
    由于在System.Collections.HashtableSystem.Collections.Generic.Dictionary以及其他一些集合的实现中,要求两个对象必须具有相同的哈希码才被视为相等。

具体例子如下,完整可参考 MSDN IEquatable.Equals(T) Method

public class Person : IEquatable<Person>
{
    private string _name;
    private string _id;

    public Person(string name, string id)
    {
        _name = name;
        _id = id;
    }

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public string Id
    {
        get{ return _id; }
        set{ _id = value; }
    }

    //自定义的Equals方法
    public bool Equals(Person other)
    {
        if (other == null) return false;

        if (_name == other.Name && _id == other.Id)
            return true;
        else
            return false;
    }
    //重写基类中的Equals方法
    public override bool Equals(object obj)
    {
        if (obj == null) return false;

        Person personObj = obj as Person;
        if (personObj == null)
            return false;
        else
            return Equals(personObj);
    }
    
    public override int GetHashCode()
    {
        return _name.GetHashCode() ^ _id.GetHashCode();
    }
}

拓展阅读:
https://www.cnblogs.com/yang_sy/archive/2014/03/07/3582946.html

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值