自定义类型的相等判断

实现自定义类型的相等性判断(参考链接),步骤如下:

  1. 重写Object.Equals(object)方法,调用IEquatable.Equals(T)进行实现;
  2. 实现IEquatable接口,在Equals(T)方法中进行自定义的相等性判断。实现时应先进行运行时类型判断,运行时类型相同才相同,然后判断关键字段是否相等;
  3. 重载==与!=运算符,非必要,但建议进行重载;
  4. 重写Object.GetHashCode()方法;

如自定义类型Student:

class Student : IEquatable<Student>
{
    public int Id { get; set; }

    public string Name { get; set; } = string.Empty;

    public int Age { get; set; }
    
    public string Remark { get; set; }

    #region IEquatable<T>实现
    // 重写Object.Equals(object)
    public override bool Equals(object obj)
    {
        return Equals(obj as Student);
    }
    
    // 实现IEquatable<T>接口
    public bool Equals(Student other)
    {
        if (other is null)
            return false;

        if (Object.ReferenceEquals(this, other))
            return true;

        // 运行时类型判断
        if (this.GetType() != other.GetType())
            return false;
        
        // 判断字段是否相等
        return Id == other.Id 
            && Name == other.Name 
            && Age == other.Age;
    }

    // 重写Object.GetHashCode()
    public override int GetHashCode()
    {
        return HashCode.Combine(Id, Name, Age);
    }
 
    // 运算符重载
    public static bool operator ==(Student left, Student right)
    {
        if (left is null)
        {
            if (right is null)
                return true;

            return false;
        }
        
        return left.Equals(right);
    }

    public static bool operator !=(Student left, Student right) => !(left == right);
    #endregion
}

看着很麻烦,代码那么多,其实,通过VS快速操作和重构可以快速实现IEquatable...

实现了IEquatable接口,就可以按照我们自定义的相等条件判断两个实例是否相等了,如果需要判断两个集合是否相等,使用Enumerable.SequenceEqual()方法:

public void StudentEqualTest()
{
    Student A = new Student { Id = 1, Name = "张三", Age = 18, Remark = "A" };
    Student B = new Student { Id = 1, Name = "张三", Age = 18, Remark = "B" };
    Student C = new Student { Id = 2, Name = "李四", Age = 20, Remark = "C" };

    Console.WriteLine($"instance A == instance B : {A == B}"); // true
    Console.WriteLine($"instance A == instance C : {A == C}"); // false

    List<Student> list1 = new List<Student> { A, C};
    List<Student> list2 = new List<Student> { B, C };

    Console.WriteLine($"list1 == list2 : {list1.SequenceEqual(list2)}"); // true
    B.Age = 19;
    Console.WriteLine($"after change B.Age, list1 == list2 : {list1.SequenceEqual(list2)}"); // false
}
posted @ 2023-07-14 17:34  louzi  阅读(39)  评论(0编辑  收藏  举报