2

C# でクラス B を継承するクラス A があるとします。クラス B にはチェックサムと呼ばれるプロパティがあり、実行時に呼び出されると、クラス A のインスタンスのすべてのプロパティのチェックサムを計算します (使用される特定のチェックサム アルゴリズムは重要ではなく、おそらく BCL のものです)。

重要なことに、チェックサム アルゴリズムはチェックサム プロパティを無視する必要があります。そうしないと、後で検証するときに失敗します (チェックサム値が変更されるため)。

したがって、私が見る限り、2つのオプションがあります。

1) リフレクションを使用してオブジェクトのすべてのパブリック プロパティを反復処理し、文字列に連結してチェックサムを取得します。

2) オブジェクトが単に一連の連続したメモリ アドレスであるふりをして、それをバイト配列とチェックサムとして扱います。

1 - 遅いように聞こえます 2 - チェックサム自体を表す文字列を無視する方法や、他のオブジェクトへの参照がどのように処理されるのかがわからないため、難しいように聞こえます。

これら 2 つのソリューションのどちらが優れているように聞こえる 1 よりも優れたアイデアを誰かが持っていますか?

4

3 に答える 3

5

チェックサムプロパティをとして装飾し、NonSerializedクラスのインスタンスをバイト配列にシリアル化してから、チェックサムを計算できます。このように、シリアル化中にプロパティは無視されます。

于 2010-01-18T11:41:03.003 に答える
2

なぜそれがプロパティでなければならないのですか?メソッド GetChecksum() の場合は、チェックサムの計算にそれ自体が含まれないようにするための特別なロジックを用意する必要はありません。ここで作成したものは、既存の GetHashCode() メソッドの目的とほぼ同じです — 代わりにこれを実装するだけです。

通常、各クラスの GetHashCode() を明示的にコーディングしますが、Web をすばやく検索すると、リフレクションを使用して一般的な (ただし低速の) メカニズムを提供するアプローチが明らかになります。通常、ハッシュコードに含めたい各フィールドを取得し、それを整数に変換して固定数で乗算し、フィールドの値が異なるさまざまなオブジェクトが、整数の範囲全体に十分に分散されたさまざまなハッシュコードを与えるようにします。

例として、Resharper は次のような GetHashCode() メソッドを生成します。

public override int GetHashCode()
{
    unchecked
    {
        int result = a;
        result = (result * 397) ^ (b != null ? b.GetHashCode() : 0);
        result = (result * 397) ^ c.GetHashCode();
        return result;
    }
}

a は int、b は文字列、c は long です。中間値 (結果) は 397 で乗算され、各ステップで次のコンポーネントのハッシュコードを累乗します。チェックされていないということは、整数がオーバーフローした場合 (その可能性が高い)、オーバーフローを破棄してラップアラウンドすることを意味します。これにより、ほとんどの場合、整数空間が適切にカバーされるはずですが、不十分なハッシュコードはシステムのパフォーマンスに深刻な影響を与える可能性があるため、カバー率をテストすることをお勧めします。

ゼロを乗算して、すべてのハッシュ コードがゼロの多数のオブジェクトになってしまわないように、フィールドのゼロを処理するように注意する必要があります。

于 2010-01-18T11:55:14.690 に答える
1

オプション 3 は、すべてのプロパティのチェックサムを計算するメソッドをオンザフライで作成することです。たとえば、reflection.emit を使用します。これは最初の呼び出しに対してのみ非効率的ですが、生成されたメソッドはキャッシュできます。チェックサムが必要な型がわかっている場合は、コード生成を使用して、コンパイル時にそれらのチェックサム メソッドを作成することもできます。

于 2010-01-18T11:47:44.947 に答える