自己尝试写出如下代码,来判断对象相等,虽然能正常工作。
using System;
namespace 比较相等
{
class Program
{
static void Main(string[] args)
{
Pet a1 = new Pet { Name = "Turbo", Age = 8 };
Pet a2 = new Pet { Name = "Turbo", Age = 8 };
if (a1.Equals(a2))
Console.WriteLine("相等");
else
Console.WriteLine("不相等");
Console.Read();
}
}
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
public bool Equals(Pet other)
{
if ((Object) other ==null)
{
return false;
}
return this.Name == other.Name && this.Age == other.Age ;
}
}
}
但是查网上的资料,发现微软官方和其他博客不仅写了 Equals(Pet other),还要重写 override Equals(object obj)。
疑惑 1:
官方说实现特定的 Equals(Pet other)是为了提高性能,这个我勉强能理解。但是为什么还要重写 Equals(object obj)呢? 它的意义何在? 或者说,什么样的情况下,明明已经有了 Equals(Pet other)不会调用 Equals(Pet other),而是去调用 Equals(object obj)?
我尝试模仿官方文档,在 Pet 类中添加了 Equals(object obj),为了强行去调用 Equals(object obj)(疑惑 1 ),还单独创建了一个类 Gdd。
using System;
namespace 比较相等
{
class Program
{
static void Main(string[] args)
{
Pet a1 = new Pet { Name = "Turbo", Age = 8 };
Gdd a2 = new Gdd { Name = "Turbo", Age = 8 };
if (a1.Equals(a2))
Console.WriteLine("相等");
else
Console.WriteLine("不相等");
Console.Read();
}
}
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
public bool Equals(Pet other)
{
if ((Object) other ==null)
{
return false;
}
return this.Name == other.Name && this.Age == other.Age ;
}
public override bool Equals(object obj)
{
if (obj == null )
{
return false;
}
Pet p = obj as Pet;
if ((Object)p == null)
{
return false;
}
return this.Name == p.Name && this.Age == p.Age;
}
}
class Gdd
{
public string Name { get; set; }
public int Age { get; set; }
}
}
疑惑 2:
从逻辑上来说,a1 和 a2 的值是相等的,此时调用的是 Equals(object obj),不过永远返回 false。
如以上代码中完全独立的两个类,怎么写 Equals 方法去判断 a1 和 a2 值相等?
因为所有类型都继承自
System.Object
,你重写的是这个父类里的方法。另外
Object
有一个静态方法ReferenceEquals()
来判断两个对象是否相等,这里面会隐式调用Equals(object obj)
,所以你要重写。再一个你写的这个其实是不对的,既然重写了
Equals()
,就一定也要同时重写GetHashCode()
。最后一个问题仅给关键代码参考吧:
以上代码是徒手写的,未经过测试,可能有谬误,自行理解一下吧。