10

で、メソッドがコンテンツを比較するのではなく、参照を比較することによって常に 2 つの間の同等性をチェックするのC#はなぜですか?Equals()arrays

結果として、Equals()実装で呼び出すすべてのメソッド (多く) は、配列で期待どおりに機能しません (コンテンツを比較しません) :

例 :

int[] array1 = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] array2 = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9};

var u = array1.Equals(array1);                                       //true
var v = array1.Equals(array2);                                       //false
var w = Array.Equals(array1, array2);                                //false
var x = (new List<int[]>(new int[][] { array1 })).Contains(array2);  //false
var y = (new int[][] { array1 }).Any(x => x == array2);              //false
var z = (new int[][] { array1, array2 }).Distinct().Count() == 1;    //false

配列を処理する一般的な方法 (タイプに関係なく) は次のようになります。

In Object.Equals(): 比較する両方のタイプが (同じ長さの) 配列である場合、項目を列挙し (常に可能)、項目ごとに を呼び出しますEquals()。これらの呼び出しのいずれかが返された場合false、配列は異なります (返されfalseます) それ以外の場合は返されtrueます。

SequenceEqual()注: 、memcmp()および2つの配列を比較する他の方法について知っています。私の質問は、配列を比較する方法ではありません。#C設計者が完全な配列比較をメソッドに実装することを選択しない理由を知りたいだけですEquals()

4

1 に答える 1

6

Microsoft のフレームワーク クラスは、残念ながらその意味に関して少し一貫性がありませんがObject.Equals(Object)、一般に、 への任意の参照を への参照に置き換えたり、その逆を行ったりしても、問題のオブジェクトのセマンティクスが変更されるとは予想されないX.Equals(Y)場合にのみ当てはまります。たとえば、がコンテンツ "Hello" を持ち、が同じコンテンツを持つ別の文字列である場合、1 つの文字列への参照を別の文字列への参照に置き換えても、一般にその動作は変わりません。2 つの文字列参照が同じ文字列を参照しているかどうかをテストするために使用するコードは切り替えに気付くかもしれませんが、通常の文字列コードはそうではありません。XYXStringYReferenceEquals

原則として、変更可能なオブジェクトは他のオブジェクトと同等ではないため、両方の参照が同じオブジェクトを参照しない限り、変更可能なオブジェクトへの参照は別のオブジェクトと同等であってはなりません。int[]同じ値を保持する の2 つの異なるインスタンスへの参照を持つことと、同じインスタンスへの 2 つの参照を持つことには大きな違いがあります。配列のすべてのアイテム、または特定の範囲のアイテムが一致したかどうかをテストするメソッドをArray持つことは役に立ちますが、 /メンバーを持つ型を持つことは役に立ちます。同じ内容であっても、異なる可変配列が内容に関係なく互いに等しくないことは完全に正しいことです。ItemsEqualImmutableArrayEqualsGetHashCode

于 2013-02-26T22:15:24.177 に答える