0

私はこの質問をここで読んで、この記事をここに導きました。

抽象基本クラス (基本ポリモーフィズム) を拡張するクラスのみを受け入れるようにメソッドを制限できる抽象基本クラスがあります。私の質問は次のとおりです:GetHashCode()具体的な実装に適切なオーバーライドを提供するために、抽象基本クラスに実装できますか? GetHashCode()(つまり、各具象クラスでのオーバーライドを避けるためです。)

私は抽象基本クラスのメソッドを次のように想像しています:

public abstract class FooBase
{
    private static readonly int prime_seed = 13;
    private static readonly int prime_factor = 7;

    public override int GetHashCode()
    {
        // Seed using the hashcode for this concrete class' Type so
        // two classes with the same properties return different hashes.
        int hash = prime_seed * this.GetType().GetHashCode();
        // Get this concrete class' public properties.
        var props = this.GetType().GetProperties(BindingFlags.Public);
        foreach (var prop in props)
        {
            // Factor in each of this concrete class' public properties' hashcodes.
            hash = (hash * prime_factor) + prop.GetHashCode();
        }
        return hash;
    }
}

これはいくつかの基本的な等価単体テストで機能するようですが、何かを見落としているように感じます。GetHashCode() をオーバーライドしないことに関するコンパイラの警告を回避するために、各具体的なクラスでオーバーライドを提供する必要がありますが、少なくともこの方法では、それぞれの実装を手動で記述する必要はありません。

4

3 に答える 3

2

これは次のものよりも優れていますか?

public override int GetHashCode()
{
    return 1;
}

ハッシュ関数の鍵は、計算が高速でなければならないことです。リフレクションを使用すると、ハッシュを使用することで得られるすべてのメリットを失う可能性があります。

ベンチマークする価値はあります。

また、Equals が true を返す場合、ハッシュ コードは等しくなければならないので、すべてのサブクラスは Equals メソッドでパブリック プロパティのみを使用するのでしょうか? そうでない場合は、パブリック プロパティだけでなく、すべてのプロパティをループすることを検討してください。

編集して追加: また、ハッシュが Int.MaxValue より大きくなった場合の例外を防ぐために、プロパティ ループの周りに uncheckedを追加することを検討してください。

于 2012-09-26T19:25:30.680 に答える
1

You missed a basic rule - GetHashCode() result must remain the same for the whole lifetime of the object. In your GetHashCode implementation, it isn't guaranteed (because the properties you are iterating can be mutable).

于 2012-09-26T19:22:57.487 に答える
0

リフレクションの使用はかなり遅くなりますが、許容できる場合もあります。GetHashCode 関数は、クラスのインスタンスがハッシュ テーブルまたはディクショナリのキーである場合に使用されます。ほとんどの場合、いつ必要になるかはわかっています。Resharper ( example ) のように、手動で記述する代わりに GetHashCode および Equals 関数を生成できるツールがいくつかあります。

于 2012-09-26T19:18:32.333 に答える