24

ID プロパティが null になる可能性があることを考えると、次のうちどれが正しい/より良いものですか。

public override int GetHashCode()
{
    if (ID == null) {
        return base.GetHashCode();
    }
    return ID.GetHashCode();
}

また

public override int GetHashCode()
{
    if (ID != null) {
        return ID.GetHashCode();
    }
     return 0;
}

更新 1: 2 番目のオプションを更新しました。

更新 2: 以下は Equals の実装です。

public bool Equals(IContract other)
{
    if (other == null)
        return false;
    if (this.ID.Equals(other.ID)) {
        return true;
    }
    return false;
}

public override bool Equals(object obj)
{
    if (obj == null)
        return base.Equals(obj);
    if (!obj is IContract) {
        throw new InvalidCastException("The 'obj' argument is not an IContract object.");
    } else {
        return Equals((IContract)obj);
    }
}

そしてIDはstring型です。

4

3 に答える 3

25

それは本当にあなたが平等を意味したいものに依存します - 重要なことは、2 つの等しいオブジェクトが同じハッシュコードを返すということです。IDがnullの場合、等価とはどういう意味ですか? 現在、ID プロパティが同じ値の場合、Equals メソッドはtrue返す必要がありますが、ID が null の場合にどうなるかはわかりません。

実際に最初のバージョンの動作が必要な場合は、個人的に使用します。

return ID == null ? base.GetHashCode() : ID.GetHashCode();

編集: Equals メソッドに基づいて、GetHashCode メソッドを作成できるようです:

return ID == null ? 0 : ID.GetHashCode();

Equals(IContract other)メソッドは次のようにもなることに注意してください。

return other != null && object.Equals(this.ID, other.ID);

this.IDnullの場合、現在の実装は実際に例外をスローします...

さらに、Equals(object)メソッドが正しくありません。不適切なオブジェクト型が渡された場合は例外をスローするべきではありません。null のfalse場合は ... 同上を返す必要objがあります。したがって、実際には次のように使用できます。

public override bool Equals(object obj)
{
    return Equals(obj as IContract);
}

ただし、インターフェイスに基づく平等については懸念があります。通常、異なるタイプの 2 つのクラスは、同じインターフェイスを実装していても、等しいと見なされるべきではありません。

于 2011-02-22T12:36:17.017 に答える
5

簡単return 0;に言えば、同じ値に対して同じ HashCode を返す必要があり、ID.GetHashCode() によって 0 が返されることはあまりないため、このようなハッシュ関数はあらゆるニーズに対応できます。値 ( ID や Name Hashes など) を組み合わせていないため、かなり明確な ID が HashCode の定義ソースであるため、Null ID の固定 0 は合理的に聞こえます。

それ以外の場合、ID フィールドのみを考慮した GetHashCode オーバーライドのアプローチ全体が間違っている可能性があります (いくつかのフィールドを組み合わせて、それらからハッシュを計算する必要があります)。

編集後、2 番目の Equals オーバーライドにはコードが多すぎると言えます。

public override bool Equals(object obj)
{
    return Equals(obj as Contract);
}

あなたの Equals(IContract コントラクト) オーバーライドは私にはバグがあるように見えます。コントラクトを定義するのは ID だけであり、IContract に ID よりも多くのフィールドがある場合は、Equals のオーバーライドが悪くなります。

PS: 実際、IContract がインターフェイスである場合は、おそらくIEquatable<IContract>具体的なIEquatable<ClassName>コントラクトに置き換える必要があります。同じインターフェイスを実装する異なるクラス インスタンスが等しいことを返すことができるようにするには、設計が不適切になるためです。等価性チェックの最初の段階で同じタイプ (通常は 99.9% の場合)

于 2011-02-22T12:40:58.557 に答える
0

おそらくあなたが欲しいのはこのようなものですか?

override int GetHashCode()
{
    if (ID != null)
        return ID.GetHashCode();

    return DBNull.Value.GetHashCode();
}

重要なことは、null ID を持つ 2 つのオブジェクトを等しいと見なす必要があるかどうかです。

于 2011-02-22T12:39:37.660 に答える