有没有人有一个用于编写正确的equals方法的模板 - 我记得在Effective Java中,在处理子类时遇到了处理equals的问题。
我没有这本书,我不记得这是否是实用的建议 - 那么你如何编写一个可靠的强大的equals方法实现?
答案 0 :(得分:12)
可能是一个离墙的建议但是:首先考虑不要覆盖Equals
。正如您所提到的,基本上,平等的性质不适用于子类化。但是,.NET API中几乎所有使用相等性的地方(例如字典,散列集)都允许传入IEqualityComparer<T>
。使另一个对象负责相等使生活变得更加灵活:您可以使用不同的对象来确定使用哪个标准。
实现IEqualityComparer<T>
要简单得多 - 您仍然需要检查是否存在无效,但是您不必担心类型是否合适,或者是否会进一步覆盖Equals
。
使普通Equals
工作更顺利的另一种方法是在大多数情况下完全避免继承 - 我不记得上次在我的代码中覆盖Equals
< em>和允许派生类。 sealed
FTW:)
答案 1 :(得分:8)
您可能已经这样做了,但是您是否查看了有关实施Equals()
的MSDN文章?
答案 2 :(得分:5)
良好的等于方法的属性:
答案 3 :(得分:5)
如果您厌倦了为此编写大量样板文件,可以尝试使用为您实现它的基类。
public abstract class ValueObject<T> : IEquatable<T>
where T : ValueObject<T>
{
protected abstract IEnumerable<object> Reflect();
public override bool Equals(Object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (obj.GetType() != GetType()) return false;
return Equals(obj as T);
}
public bool Equals(T other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Reflect().SequenceEqual(other.Reflect());
}
public override int GetHashCode()
{
return Reflect().Aggregate(36, (hashCode, value) => value == null ?
hashCode : hashCode ^ value.GetHashCode());
}
public override string ToString()
{
return "{ " + Reflect().Aggregate((l, r) => l + ", " + r) + " }";
}
}
现在要创建一个类似于类的类,你只需说:
public class Person : ValueObject<Person>
{
public int Age { get; set; }
public string Name { get; set; }
protected override IEnumerable<object> Reflect()
{
return new object[] { Age, Name };
}
}
在Reflect
覆盖中,您将返回一系列需要促成相等的值。
不幸的是,这种方法无法帮助声明operator ==
,因为必须在派生类型上明确声明。
答案 4 :(得分:2)
答案 5 :(得分:1)
我通常做这样的事情:
public struct EmailAddress : IEquatable<EmailAddress>
{
public override bool Equals(object obj)
{
return obj != null && obj.GetType() == typeof(EmailAddress) && Equals((EmailAddress)obj);
}
public bool Equals(EmailAddress other)
{
return this.LocalPart == other.LocalPart && this.Domain == other.Domain;
}
}
答案 6 :(得分:0)
“好”等于方法是一种方法,它比较类的唯一部分,同时省略不贡献唯一性的部分。因此,如果你有一个id为唯一的类,你可以使用它来建立相等,而忽略任何其他属性。但是,你通常也需要一些时间戳值。
答案 7 :(得分:0)
公共类人员 { public string Name {get;组; }
public int Age { get; set; }
public override bool Equals(object obj)
{
var objAsPerson = obj as Person;
if (obj == null)
{
return false;
}
if (this.Name != objAsPerson.Name)
{
return false;
}
if (this.Age != objAsPerson.Age)
{
return false;
}
return true;
}
}