短い答え:一貫性
しかし、あなたの質問に適切に答えるために、私たちは一歩後退して、プログラミング言語で平等が意味することの問題に目を向けることをお勧めします。少なくとも3つの異なる可能性があり、さまざまな言語で使用されています。
- 参照の等価性:aとbが同じオブジェクトを参照する場合、a = bが真であることを意味します。aとbのすべての属性が同じであっても、aとbが異なるオブジェクトを参照している場合は当てはまりません。
- 浅い等価性:aとbが参照するオブジェクトのすべての属性が同一である場合、a = bが真であることを意味します。浅い等価性は、2つのオブジェクトを表すメモリ空間のビットごとの比較によって簡単に実装できます。参照の平等は浅い平等を意味することに注意してください
- 深等性:aとbの各属性が同一または完全に等しい場合、a = bが真であることを意味します。深い等価は、参照等価と浅い等価の両方によって暗示されることに注意してください。この意味で、深い平等は平等の最も弱い形であり、参照平等は最も強いです。
これら3つのタイプの等式は、実装が便利であるためによく使用されます。3つの等式チェックはすべて、コンパイラーによって簡単に生成できます(深い等式の場合、コンパイラーは、タグビットを使用して無限ループを防ぐ必要がある場合があります比較されるのは循環参照です)。しかし、別の問題があります。これらはどれも適切ではないかもしれません。
自明でないシステムでは、オブジェクトの平等はしばしば深い平等と参照平等の間の何かとして定義されます。特定のコンテキストで2つのオブジェクトを同等と見なすかどうかを確認するには、一部の属性をメモリ内の位置で比較し、他の属性を完全に異なるものとすることができますが、一部の属性はまったく異なるものにすることができます。私たちが本当に望んでいるのは、「フォースタイプの平等」であり、文学のセマンティック平等でしばしば呼ばれる、本当に素晴らしいものです。私たちのドメインでは、物事が等しければ等しいです。=)
それで、あなたの質問に戻ることができます:
これをデフォルトにすることでいくつかの大きな利点がありますか、それとも単にデフォルトの動作が論理的等価であるべきであり、クラスに論理的等価が存在しない場合はデフォルトを参照等価に戻すのが妥当と思われますか?
「a == b」を任意の言語で書くとき、どういう意味ですか?理想的には、常に同じである必要があります:意味的平等。しかし、それは不可能です。
主な考慮事項の1つは、少なくとも数値のような単純な型の場合、同じ値を代入した後は2つの変数が等しいと予想されることです。下記参照:
var a = 1;
var b = a;
if (a == b){
...
}
a = 3;
b = 3;
if (a == b) {
...
}
この場合、両方のステートメントで「aはbに等しい」と予想されます。他のものはすべて異常です。ほとんどの言語(すべてではないにしても)は、この規則に従います。したがって、単純型(値とも呼ばれます)を使用すると、セマンティックな等価性を実現する方法がわかります。オブジェクトの場合、それはまったく異なるものになる可能性があります。下記参照:
var a = new Something(1);
var b = a;
if (a == b){
...
}
b = new Something(1);
a.DoSomething();
b.DoSomething();
if (a == b) {
...
}
最初の「if」は常に真であると期待しています。しかし、2番目の「if」では何を期待しますか?それは本当に依存しています。'DoSomething'は、aとbの(セマンティック)平等を変更できますか?
セマンティックな等価性の問題は、コンパイラがオブジェクトに対して自動的に生成できないこと、および割り当てから明らかであることです。ユーザーが意味的同等性を定義するためのメカニズムを提供する必要があります。オブジェクト指向言語では、そのメカニズムは継承メソッドequalsです。OOコードの一部を読んで、メソッドがすべてのクラスでまったく同じ実装を持つことは期待できません。継承とオーバーロードに慣れています。
ただし、演算子では、同じ動作が期待されます。「a == b」と表示された場合、すべての状況で同じタイプの同等性(上記4)が期待されます。そのため、一貫性を目指して、言語設計者はすべての型に対して参照の平等を使用していました。プログラマがメソッドをオーバーライドしたかどうかに依存すべきではありません。
PS:言語DeeはJavaおよびC#とわずかに異なります:等号演算子は、単純型の浅い等価性とユーザー定義クラスのセマンティックな等価性を意味します(ユーザーにある=操作を実装する責任がある-デフォルトは提供されません)。単純型の場合、浅い等式は常に意味的等式であるため、言語は一貫しています。ただし、代価は、等号演算子がデフォルトでユーザー定義型に対して未定義であるということです。実装する必要があります。そして、時々、それはただ退屈です。