2

2 つのクラスのインスタンスを辞書構造に格納し、IEquatable を使用してこれらのインスタンスの一意性を判断したいと考えています。これらのクラスは両方とも (抽象) 基本クラスを共有します。次のクラスを検討してください。

abstract class Foo
{
   ...
}

class SubFoo1 : Foo
{
   ...
}

class SubFoo2 : Foo
{
   ...
}

辞書は次のように宣言されます。Dictionary<Foo, Bar>

どのクラスを IEquatable として宣言する必要がありますか? そして、これらの宣言のジェネリック型 T は何であるべきでしょうか? これは可能ですか?

4

5 に答える 5

4

として何も宣言しないでくださいIEquatable<T>。マークが言うように、継承と平等に関しては一般的に問題です。

代わりに、この特定のディクショナリのキーに対してどのような種類の等価性が必要かを判断し、 を実装しIEqualityComparer<Foo>てから、それをディクショナリ コンストラクタに渡します。

通常、特定の状況でキーを比較する方法はかなり明確です。

于 2010-04-22T21:26:23.750 に答える
0

継承可能なクラスは、ほとんど実装しないでくださいIEquatable<T>。どのタイプTの場合でも、実装するすべてのオブジェクトIEquatable<T>は、のセマンティクスがのセマンティクスIEquatable<T>.Equalsと一致するように実行する必要がありObject.Equalsます。IEquatable<Foo>クラスが一部を実装しFoo、派生クラスがのセマンティクスを変更するObject.Equalsが再実装しないIEquatable<Foo>.Equals場合、後者のセマンティクスが前者と一致する唯一の方法は、インターフェイス実装が単に仮想Object.Equals自体を呼び出す場合です。インターフェイスが単に引数をに渡す場合、Object.Equalsそれを実装するメリットはありません。

于 2012-06-13T00:16:51.100 に答える
0

それは、クラスが何を表しているかによって異なります。したがって、それに対する「一般的な」解決策はありません。存在する場合は、とにかくすべてが既に継承されているため、System.Object実装します。したがって、の代わりに同じ質問をすることもできます。IEquatable<object>objectObjectFoo

簡単に言えば、クラス階層で何を達成したいかによって異なります。

簡単に言えば、同じオブジェクト タイプであっても、要件が異なる可能性があるため、オブジェクトを同等にするものを決定するのは難しいことに同意します。キャッシュを使用する場合、等価性はオブジェクトのエンティティ ID によって決定されます。Do-/Undo-List を使用する場合、ID はおそらくリスト内の各オブジェクトで同じであるため、別の修飾子が必要になります。

少し脱線しましたが、参考になれば幸いです。;-)

于 2010-04-22T21:16:17.670 に答える
0

継承を取得し始めると、T. Equalsbase-type は当然の選択ですが、 andをオーバーライドするだけの方が適切ではないのでしょうかGetHashCode

また、このような複雑なシナリオはキーの選択として不適切である可能性があり、代わりに、より単純で予測可能なキーを使用する可能性があると結論付けるかもしれません。特に、「ハッシュ」は型の不変ファセットに基づく必要があり、「ハッシュ」と「等しい」は互換性がなければなりません。型が ではない場合、これらのニュアンスを保証するのは非常に困難ですsealed

于 2010-04-22T21:20:25.297 に答える
0

ディクショナリ コンストラクタで独自の等値比較子をいつでも指定できます。IEquatable<TKey>そうしないと、辞書はあなたのケースでそう探しますので、IEquatable<Foo>それを実装する必要があります。

于 2010-04-22T21:26:38.450 に答える