提问人:isakgo_ 提问时间:7/11/2022 更新时间:7/11/2022 访问量:68
对于以其他类的对象为成员的类,应该如何实现相等性检查?
How should I implement equality checking for classes that have objects of other classes as member?
问:
我有一个类,它有一个类的对象。Student
Name
此时,类的相等性检查返回false,我不知道为什么。Student
public class Student : IEquatable<Student>
{
public Name Name { get; }
public Student(Name name) => Name = name;
public bool Equals(Student other)
{
if (ReferenceEquals(this, other))
return true;
if (ReferenceEquals(other, null))
return false;
return Name == (other.Name);
}
}
public class Name : IEquatable<Name>
{
public string First { get; }
public Name(string first) => First = first;
public bool Equals(Name other)
{
if (ReferenceEquals(this, other))
return true;
if (ReferenceEquals(other, null))
return false;
return First == other.First;
}
}
var s1 = new Student(new Name("A"));
var s2 = new Student(new Name("A"));
Console.WriteLine(s1.Equals(s2).ToString());
当然,以这种方式进行相等性检查将返回 true。
var s1 = new Student(new Name("A"));
var s2 = s1;
Console.WriteLine(s1.Equals(s2).ToString());
你能告诉我我做错了什么吗?
答:
3赞
Etienne de Martel
7/11/2022
#1
因此,默认情况下,引用类型仅比较引用。实现不会自动重载,您必须自己完成。 会重载该运算符,因此它在 中起作用,但您的类不起作用,因此在 中,使用默认行为,这相当于 。==
IEquatable<T>
==
string
Name
Name
Student
ReferenceEquals()
正确实现还意味着您需要覆盖 和 ,而这里没有这样做。IEquatable<T>
Equals(object)
GetHashCode()
2赞
Yong Shun
7/11/2022
#2
解决方案 1(推荐)
由于您已经实现了类的接口,因此只需在类中调用即可。IEquatable
Name
.Equals()
Student
public class Student : IEquatable<Student>
{
public Name Name { get; }
public Student(Name name) => Name = name;
public bool Equals(Student other)
{
if (ReferenceEquals(this, other))
return true;
if (ReferenceEquals(other, null))
return false;
return Name.Equals(other.Name); // Replaces with .Equals
}
}
示例 .NET Fiddle(解决方案 1)Sample .NET Fiddle (Solution 1)
解决方案 2
或者,您需要为 and 运算符实现运算符重载。==
!=
如果在以下位置使用运算符:==
public class Student : IEquatable<Student>
{
...
public bool Equals(Student other)
{
...
return Name == (other.Name);
}
}
public class Name : IEquatable<Name>
{
...
public static bool operator == (Name a, Name b)
{
return a.First == b.First;
}
public static bool operator != (Name a, Name b)
{
return a.First != b.First;
}
}
评论
System.Collections.Generic.EqualityComparer<T>.Default.Equals(o1, o2)
==
==
Equals()
IEquatable
IEquatable<T>.Equals(T other)
Object.Equals(object other)