有没有人有一个模板来编写一个像样的equals方法 - 我记得在Effective Java中,在处理子类时遇到了处理equals的问题.
我没有这本书,我不记得这是否是实用的建议 - 所以你如何编写一个稳固的强大的equals方法实现?
Jon*_*eet 12
可能是一个离墙的建议,但是:首先考虑不要压倒一切Equals.正如您所提到的,基本上,平等的性质不适用于子类化.但是,.NET API中使用相等的几乎所有地方(例如字典,散列集)都允许IEqualityComparer<T>传入.使不同的对象负责相等使生活变得更加灵活:您可以使用不同的对象来确定要使用的标准.
实现IEqualityComparer<T>更简单 - 您仍然需要检查是否为null,但您不必担心类型是否合适,或者是否Equals将进一步覆盖.
使正常Equals工作更顺利的另一种方法是在大多数情况下完全避免继承 - 我不记得上次在我的代码中覆盖Equals 和允许派生类真正有意义.sealedFTW :)
良好等于方法的属性:
如果您厌倦了为此编写大量样板文件,可以尝试使用为您实现它的基类.
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) + " }";
}
}
Run Code Online (Sandbox Code Playgroud)
现在要做一个类似于价值的课程,你只需说:
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 };
}
}
Run Code Online (Sandbox Code Playgroud)
在Reflect覆盖中,您将返回需要促成相等性的一系列值.
不幸的是,这种方法无法帮助声明operator ==,因为必须在派生类型上明确声明.
| 归档时间: |
|
| 查看次数: |
7079 次 |
| 最近记录: |