2012-04-11 8 views
19

可能性の重複:
Why ReferenceEquals and == operator behave different from Equalsなぜデフォルト==実装は等価を呼び出さないのですか?

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

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

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

+2

「同等」は何を使用する必要がありますか? – Oded

+1

デザインによって、Javaに似て、本当に。 –

+2

@JamesMichaelHare、デザインの決定はどこからも来ていません... – SiberianGuy

答えて

5

Object.ReferenceEqualsはstaticのメンバーで、の参照と同等です。偶数の値の型は、そのメソッドに渡される前に囲まれています。

Equalsについて何、それはオーバーライド機能への消費者にすることができます意味virtual方法、です。

ので==行動のデフォルト実装では、この場合の具体的な何か、フレームワークは上書きすることができvirtual方法、を提供しますが必要な場合は、デフォルトの比較(参照)は、あなたのためokです前提としています。私は主な理由は==であると考えてい

+1

デフォルトの比較(参照)は私にとっては問題ではなく、Equalsをオーバーライドしますが、なぜ==と!=を指定する必要がありますか?私がEqualsをオーバーライドするときのユースケースは何ですか?しかし、依然として==と!=が必要です。 – SiberianGuy

+0

@Idsa:あなたがそうしたいのなら、それは混乱の真の方法です:)。指定されたタイプの比較方法は* 1つでなければなりません。私はそれがフレームワークのデザイナーの元のアイデアだと思う。 "私はこのオブジェクトを比較する一つの方法を定義し、あいまいさを避けるために単一の可能な方法でなければなりません"。 – Tigran

8

静的演算子であり、Equalsはインスタンスを必要とするnullオブジェクトで呼び出すことができます。例えば

Foo foo1 = null; 
Foo foo2 = null; 

Console.WriteLine(foo1 == foo2); // cannot use Equals 
+1

しかし、Object.ReferenceEqualsも静的メソッド – SiberianGuy

1

は==が(結果はのために同じであっても回避されて、基準のために使用Cので、それはむしろメソッド呼び出しに応答することよりも、言語構文に組み込まいましたどちらも)。 C#は客観C :)

2

「理由」はないので、時には一つは、彼らは単に「等しいか否かとは対照的に、がBと同じインスタンスであるかどうかを知る必要があるため

単に、あります" お互いに。

たとえば、お互いに等しいオブジェクトが2つのビジネスロジックのほとんどに当てはまるかもしれませんが、アトミック操作を行ういくつかの並行性ユーティリティを使用する必要があります。 。

+1

ですが、この場合Object.ReferenceEqualsがあります。 – SiberianGuy

+2

Javaにはありません...この質問のタグも付けられています。 –

+1

実際の質問は、C#言語を設計する前に10年間実際にJavaを見たことの利点と知識をすべて持っていたときに、C#設計者がこれを行った理由です。私の推測は一貫性があります。 –

0

Javaでは、単純に参照を比較するだけで、2つの識別子が等しいかどうかを素早く判断することは時々役に立ちます。 ==にはそれがあります。 IDEで生成されたequalsメソッドを見ると、最初に行われた比較が参照の平等であることがわかります。結局のところ、オブジェクト参照が同じである場合にフィールドをチェックするのはなぜですか?

0

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

文字列を使用すると、==が上書きされてしまい、好きではありません。 stringは参照型ですが、参照(7.9.7文字列等価演算子)ではなく、文字列オブジェクトの値を比較するために等価演算子(==および!=)が定義されています。これにより、文字列の等価性のテストがより直感的になります。これが導入した問題を参照してください。 WPF ListBox Scroll to the bottom

関連する問題