域类T
的类型可以是ValueObject<T>
:
public class Coordinate: ValueObject<Coordinate>
{ ... }
ValueObject<T>
实现IEquatable
接口。我希望ValueObject<T>
的每个具体实现为bool Equals(T obj)
提供实现,因此我将其创建为抽象方法:
public abstract class ValueObject<T> : IEquatable<T>
{
public abstract bool Equals(T obj);
public static bool operator ==(ValueObject<T> obj1, ValueObject<T> obj2)
{
if (object.ReferenceEquals(obj1, obj2)) return true;
if (object.ReferenceEquals(obj1, null)) return false;
if (object.ReferenceEquals(obj2, null)) return false;
return obj1.Equals(obj2);
}
}
Coordinate
类中的Equals实现:
public class Coordinate : ValueObject<Coordinate>
{
// ...
public override bool Equals(Coordinate other)
{
return (other != null) && (this.Latitude == other.Latitude) && (this.Longitude == other.Longitude);
}
}
ValueObject<T>
为==(和for = =,上面未显示)提供了通用操作覆盖,适用于所有具体实现。
问题是,当从==覆盖调用Equals
方法时,它会调用Object.Equals()
而不是Coordinate.Equals()
。
答案 0 :(得分:6)
问题是,当从
Equals
覆盖调用==
方法时,它会调用Object.Equals()
而不是Coordinate.Equals()
。
不,问题是那些东西是不同的。如果它们是相同的,那么它就没有问题了。
所以让他们一样。不要让派生阶级做错事; 强迫他们做正确的事。
public abstract class ValueObject<T> : IEquatable<T>
{
// Force the derived class to override these.
public abstract override bool Equals(object obj);
public abstract override int GetHashcode(object obj);
// And then consistently use the overridden method as the implementation.
public virtual bool Equals(T obj)
{
return obj1.Equals((object)obj2);
}
public static bool operator ==(ValueObject<T> obj1, ValueObject<T> obj2)
{
return obj1.Equals((object)obj2);
}
public static bool operator !=(ValueObject<T> obj1, ValueObject<T> obj2)
{
return !obj1.Equals((object)obj2);
}
}
答案 1 :(得分:1)
当您说obj1.Equals(obj2)
时,obj2
的{{1}}类型与ValueObject<T>
中的T
不符。
实际上,在运行时它可能与public abstract bool Equals(T obj)
不同。
在这种情况下,你可能想要返回false。
T
我认为你认为public static bool operator ==(ValueObject<T> obj1, ValueObject<T> obj2)
{
if (object.ReferenceEquals(obj1, obj2)) return true;
if (object.ReferenceEquals(obj1, null)) return false;
if (object.ReferenceEquals(obj2, null)) return false;
if (obj1.GetType() != obj2.GetType()) return false; //new
return ((T)(object)obj1).Equals((T)(object)obj2);
}
等于T
的派生类。你可以说ValueObject<T>
。这至少会编码您在类型系统中所需的部分内容,并为您节省where T : ValueObject<T>
演员阵容。