26

重複の可能性:
ReferenceEquals と == 演算子が Equals と異なる動作をする理由

operatorのデフォルトの実装は==、参照によってオブジェクトを比較します。したがって、Equals (デフォルトの動作は同じ) をオーバーライドする場合は、==and演算子も指定して、Equals を呼び出すようにする必要があります (また、 and演算子は仮想ではないため!=、階層のすべてのクラスでそれを作成します)。==!=

私の質問は、なぜそうなのかということです。Equals を使用する代わりに参照によってオブジェクト==を比較するのはなぜですか? !=そんな根本的なことには理由があるはずです。

アップデート。

コメントへ:==基本クラスでEqualsをオーバーライドし、派生クラスでこの実装を自動的に使用できるため、Equalsに依存する必要があると想定しました(ただし、その逆はありません)。仮想ではない==ため、実装にEquals を使用すると機能しません。==

4

6 に答える 6

9

主な理由は==静的演算子であり、インスタンスが必要なnullときにオブジェクトで呼び出すことができると思います。Equals

例えば:

Foo foo1 = null;
Foo foo2 = null;

Console.WriteLine(foo1 == foo2); // cannot use Equals
于 2012-04-11T16:17:05.250 に答える
5

Object.ReferenceEquals は、参照の等価性staticを比較するメンバーです。値の型でさえ、そのメソッドに渡される前にボックス化されます。

どうですかEquals、それはvirtualメソッドです。つまり、消費者が機能をオーバーライドできるようにします。

したがって、==動作のデフォルトの実装は、デフォルトの比較(参照)が適切であると想定しています。特定の何かが必要な場合、この場合、フレームワークはオーバーライド可能virtualなメソッドを提供します。

于 2012-04-11T16:16:29.027 に答える
2

「理由」は、Aが単に互いに「等しい」かどうかではなく、 Aが B と同じインスタンスであるかどうかを知る必要がある場合があるためです。

たとえば、2 つのオブジェクトが互いに等しいことは、ほとんどのビジネス ロジックにとって理にかなっているかもしれませんが、結果がオブジェクトの同一性に依存し、等しいかどうかに依存するアトミック操作を実行するいくつかの同時実行ユーティリティを利用する必要がある場合もあります。

于 2012-04-11T16:37:12.407 に答える
1

== はC以来存在し、参照用に使用されており、メソッド呼び出しで応答する必要はなく、言語構文に統合されています(両方の結果が同じであっても)。

単純に、C# は Objective C ではないためです :)

于 2012-04-11T16:31:19.190 に答える
0

私はそれを特徴と呼んでいます。参照により、2 つの同一のオブジェクトは 2 つの別個のオブジェクトのままです。Equals をオーバーライドすると、2 つのオブジェクトが同一かどうかを判断できます。2 つのオブジェクトが同一であっても、それらが同じオブジェクトであるかどうかをテストすることもできます。equals をオーバーライドする理由はよくありますが、 == != をオーバーライドする必要はありませんでした (ただし、その言語はそのオプションを提供します)。

文字列では == をオーバーライドしますが、私はそれが好きではありません。文字列は参照型ですが、等値演算子 (== および !=) は、参照 (7.9.7 文字列等値演算子) ではなく、文字列オブジェクトの値を比較するために定義されています。これにより、文字列が等しいかどうかのテストがより直感的になります。これが導入した問題を参照してください。 WPF ListBox 一番下までスクロール

于 2012-04-11T17:12:52.847 に答える
0

Java では、参照を比較するだけで 2 つの識別子が等しいかどうかをすばやく判断できると便利な場合があります。==場所があります。IDE で生成されたequalsメソッドを見ると、最初に行われる比較が参照の等価性であることがよくわかります。結局のところ、オブジェクト参照が同じである場合、なぜフィールドをチェックするのでしょうか?

于 2012-04-11T16:42:04.857 に答える