我认为在==下面的代码中的重载是不必要的,因为==已经比较了引用,如果没有重载。请告诉我方式。它应该使用单个参数Equals和单独包含的null比较来完成吗?
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public override bool Equals(object param)
{
// If the cast is invalid, the result will be null
Student student = param as Student;
// Check if we have valid not null Student object
if (student == null)
{
return false;
}
// Compare the reference type member fields
if (!Object.Equals(this.Name, student.Name))
{
return false;
}
// Compare the value type member fields
if (this.Age != student.Age)
{
return false;
}
return true;
}
public static bool operator ==(Student student1, Student student2)
{
return Student.Equals(student1, student2);
}
public static bool operator !=(Student student1, Student student2)
{
return !(Student.Equals(student1, student2));
}
...
}
答案 0 :(得分:3)
我认为在==下面的代码中的重载是不必要的,因为==已经比较了引用,如果没有重载。
是的,但重点是因为运算符已经过载,您可以比较值的相等而不是引用标识。例如:
Student x = new Student { Name = "Jon", Age = 37 };
Student y = new Student { Name = "Jon", Age = 37 };
Console.WriteLine(x == y); // Prints True
如果没有运算符重载,上面的代码会打印False
,因为x
和y
的值引用了不同的对象。
这有时比显式调用Equals
方法更方便。
因此,虽然在此处重载==
并非严格必要(因为可以通过其他方式实现相同的结果),但 会影响行为。通过任何方式为所有类型重载==
并不是一个好主意,但它可以使某些类型的事情变得简单得多。例如,我很高兴string
重载==
。关于何时重载==
的好主意的讨论超出了这个答案的范围,幸运的是 - 对于初学者来说,这是一个有争议的问题。我对类很少这样做,但几乎总是对于值类型。 (编写自定义值类型非常罕见。)常规灰色区域是不可变引用类型...
请注意,当操作数是正确的编译时类型时,重载仅 。例如:
Student x = new Student { Name = "Jon", Age = 37 };
object y = new Student { Name = "Jon", Age = 37 };
Console.WriteLine(x == y); // Prints False
此处使用了 ,因为y
的编译时类型为object
,而不是Student
。
另一方面,这是一个可变类,它覆盖Equals
,因此可能是GetHashCode
,这是一个值得关注的问题。在实例可以以影响相等性的方式改变的类中覆盖Equals
通常是个坏主意。它不适用于使用相等和散列的集合。例如:
var dictionary = new Dictionary<Student, string>();
var student = new Student { Name = "Jon", Age = 37 };
dictionary[student] = "foo";
Console.WriteLine(dictionary.ContainsKey(student)); // True
dictionary.Name = "Bob";
Console.WriteLine(dictionary.ContainsKey(student)); // False
Console.WriteLine(dictionary.Keys.First() == student); // True!
因为名称已更改,哈希代码已更改(我假设使用名称和年龄的相当简单的哈希代码实现)。这意味着正常的哈希检查将失败,即使引用仍在字典中。
如果你没有在之后将键添加到字典中,那么可以改变,但是它会使这些类型更容易出错,可以这么说。
答案 1 :(得分:1)
不必要且适得其反。在C#中,应用于类类型对象的==
用于检查标识,而不是值相等。将==
重载为equals
是令人困惑和非惯用的,并且可能会导致某些容器类型出现问题。