已知类型Person定义如下:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public override int GetHashCode()
{
return Name.GetHashCode() ^ Age;
//return base.GetHashCode();
}
public override bool Equals(object obj)
{
Person target = obj as Person;
if (target == null) return false;
return target.Name == this.Name && target.Age == this.Age;
//return base.Equals(obj);
}
}
以下代码输出内容
Person p1 = new Person { Name = "Franklin", Age = 18 };
Person p2 = new Person { Name = "Franklin", Age = 18 };
Console.WriteLine(p1.Equals(p2));
Console.WriteLine(p1==p2);
true
false
以下代码输出内容
Person p1 = new Person { Name = "Franklin", Age = 18 };
Person p2 = new Person { Name = "Franklin", Age = 18 };
var dict = new Dictionary<Person, string>();
dict.Add(p1, p1.Name);
dict.Add(p2, p2.Name);
Console.WriteLine(dict[p2]);
无法进项正常输出,因为该键已经存在,dict.Add(p2,p2.name);会报错。
代码解析:
Equals方法主要用于比较两个对象是否相等,相等为true,否则为false
如果是引用类型的对象,则用于判断两个对象是否引用了同一个对象。
在 C# 语言中,Equals 方法提供了两个,一个是静态的,一个是非静态的,具体的定义如下:
Equals (object ol, object o2); //静态方法
Equals (object o); //非静态方法
GetHashCode 方法返回当前 System.Object 的哈希代码,每个对象的哈希值都是固定的。
该方法不含有任何参数,并且不是静态方法,因此需要使用实例来调用该方法。
由于该方法是在 Object 类中定义的,因此任何对象都可以直接调用该方法。
相等的两个对象返回相等的哈希码。但是,事实并非如此:相等的哈希码并不意味着对象相等,因为不同的(不相等)对象可以具有相同的哈希码。此外,.NET不保证GetHashCode方法的默认实现,并且此方法返回的值在.NET实现(例如不同版本的.NET Framework和.NET Core)以及平台(例如32位和64位平台。由于这些原因,请勿将此方法的默认实现用作唯一的对象标识符以进行哈希处理。由此产生两个后果:
您不应假定相等的哈希码表示对象相等。您永远不要在创建它的应用程序域之外持久化或使用哈希码,因为同一对象可能会在应用程序域,进程和平台之间哈希。
Dictionary<TKey,TValue> 类实现为哈希表,键值对,用键检索的速度接近于o(1)。
此代码,重写哈希码,返回的是值类型的哈希码,所以第一个输出是false,第二个是C#里默认Equals等价于==。
拓展:
- String是引用类型,但是他重写了equals,只要字符相同,就返回true。
- 哈希码只有在作为集合索引时才起作用,平时根本用不上(来自:https://www.cnblogs.com/tonytonglx/articles/2079963.html)