2

ドメイン クラス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>== (および、上には示されていない !=) の一般的な操作のオーバーライドを提供します。これは、すべての具体的な実装に適用されます。

問題は、メソッドが == オーバーライドから呼び出されたときに、 ではなくEqualsを呼び出すことです。Object.Equals()Coordinate.Equals()

4

2 に答える 2

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);
    }
}
于 2014-03-15T14:42:35.213 に答える
1

というとobj1.Equals(obj2)、in に合わないobj2タイプです。ValueObject<T>Tpublic abstract bool Equals(T obj)

実際、実行時に とは異なるクラスになる可能性がありますT

おそらく、その場合は false を返したいでしょう。

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>。これにより、型システムで必要なものの少なくとも一部がエンコードされ、(object)キャストが節約されます。

于 2014-03-15T14:22:41.350 に答える