关于这个主题有一个很好的问题和答案: 我必须在新类中覆盖 GetHashCode 和 Equals 吗?
正如它所提到的:
如果您需要值相等语义,您只需要覆盖它们。System.Object 实现并不“坏”,它只是做一个引用检查(这是该级别的所有实现都可以做的)。
简而言之:如果您需要某种基于值的相等性(基于类属性的相等性),那么是的,覆盖掉。否则,它应该已经很好了。
假设我有一个类用户:
public class User: IEquatable<User>
{
private readonly string _firstName;
private readonly string _lastName;
private readonly string _address;
public User (string firstName, string lastName, string address)
{
this._firstName = firstName;
this._lastName = lastName;
this._address = address;
}
public FirstName {get; private set;}
public LastName {get; private set;}
public Address {get; private set;}
//should I need to override this?
public override bool Equals(object right)
{
if (object.ReferenceEquals(right, null))
return false;
if (object.ReferenceEquals(this, right))
return true;
if (this.GetType() != right.GetType())
return false;
return this.Equals(right as User);
}
#region IEquatable<User> Members
public bool Equals(User user)
{
bool isEqual = (this._firstName != null && this._firstName.Equals(user.FirstName, StringComparison.InvariantCultureIgnoreCase)) ||
(this._lastName != null && this._lastName.Equals(user.LastName, StringComparison.InvariantCultureIgnoreCase)) ||
(this._address != null && this._address.Equals(user.Address, StringComparison.InvariantCultureIgnoreCase)) ||
(this._firstName == null && this._lastName == null && this._address == null);
return isEqual;
}
#endregion
}
User user1 = new User("John", "Wayne", "Collins Avenue");
User user2 = new User("John", "Wayne", "Collins Avenue");
//if I don't override these methods, reference equals will be:
user1 == user2 // false
//if I override GetHashCode and Equals methods, then:
user1 == user2 //true
IList<User> usersList1 = new List<User>();
IList<User> usersList2 = new List<User>();
usersList1.Add(user1);
usersList2.Add(user2);
IList<User> finalUsersList = usersList1.Union(usersList2);
//if I don't override these methods, count will be:
finalUsersList.Count() // 2
//if I do override these methods, count will be:
finalUsersList.Count() // 1
这样对吗?
- 需要注释的第一个 Equals 覆盖方法?
在这种情况下,我应该在 GetHashCode 覆盖中包含哪些类成员?参与 Equals 方法的所有成员?
public override int GetHashCode() { unchecked { // Hash -> primes int hash = 17; hash = hash * 23 + FirstName.GetHashCode(); hash = hash * 23 + LastName.GetHashCode(); hash = hash * 23 + Address.GetHashCode(); return hash; } }
例如,如果我只使用 FirstName 会发生什么?