在C#中,为什么数组上的Equals()方法只比较它们的引用,而不是它们的实际内容

时间:2021-02-01 05:27:26

In C#, why Equals() method always check equality between two arrays by comparing the references the and not by comparing the content ?

在C#中,为什么Equals()方法总是通过比较引用而不是通过比较内容来检查两个数组之间的相等性?

As a consequence, all methods calling Equals() in their implementation (a lot) does not work as expected with arrays (it does not compare the content) :

因此,所有在其实现中调用Equals()的方法(很多)都不能像数组那样工作(它不会比较内容):

Example :

示例:

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

A possible generic way to handle arrays (no mater the type) could be :

处理数组的可能通用方法(无类型)可以是:

In Object.Equals() : if both types to compare are arrays (of same length), enumerate items (always possible), for each item, call Equals(). If one of these calls return false, array are different (return false) otherwise return true.

在Object.Equals()中:如果要比较的两个类型都是数组(长度相同),枚举项目(总是可能的),对于每个项目,调用Equals()。如果其中一个调用返回false,则数组不同(返回false)否则返回true。

Note : I know about SequenceEqual(), memcmp() and other ways to compare two arrays. My question is not about how to compare arrays. I just want to know why C# designers dont choose to implement a full array comparaison in Equals() method.

注意:我了解SequenceEqual(),memcmp()以及比较两个数组的其他方法。我的问题不是如何比较数组。我只是想知道为什么C#设计者不选择在Equals()方法中实现完整的数组比较。

1 个解决方案

#1


5  

Although Microsoft's Framework classes are unfortunately a bit inconsistent with regard to what Object.Equals(Object) means, in general X.Equals(Y) will only be true if replacing arbitrary references to X with references to Y, and/or vice versa, would not be expected to alter the semantics of the objects in question. For example, if X is a String with the content "Hello", and Y is a different string with that same content, replacing references to one string with references to the other would not generally alter their behavior. Although code which uses ReferenceEquals to test whether two string references refer to the same string might notice the switch, normal string code would not.

尽管微软的Framework类在Object.Equals(Object)的含义方面有点不一致,但一般来说X.Equals(Y)只有在用Y引用替换X的任意引用时才会为真,反之亦然,不会期望改变有问题的对象的语义。例如,如果X是具有内容“Hello”的字符串,并且Y是具有相同内容的不同字符串,则将对一个字符串的引用替换为对另一个字符串的引用通常不会改变它们的行为。虽然使用ReferenceEquals测试两个字符串引用是否引用相同字符串的代码可能会注意到该开关,但普通字符串代码不会。

As a general rule, no mutable object is equivalent to any other, and thus no reference to a mutable object should be equivalent to another unless both references refer to the same object. There is a big difference between having references to two different instances of int[], both of which hold the same values, versus having two references to the same instance. While it would be helpful for Array to have ItemsEqual methods which would test whether all items of the arrays, or certain ranges of items, matched, and it would be helpful to have an ImmutableArray type with a Equals/GetHashCode members that would regard as equal two immutable arrays with the same content, it is entirely right and proper that distinct mutable arrays compare unequal to each other regardless of content.

作为一般规则,任何可变对象都不等同于任何其他对象,因此除非两个引用引用同一对象,否则对可变对象的引用应该等同于另一个。对两个不同的int []实例的引用之间存在很大差异,两个实例都具有相同的值,而对同一个实例有两个引用。虽然使用ItemsEqual方法来测试数组中的所有项目或某些项目范围是否匹配会有所帮助,但是使用具有Equals / GetHashCode成员的ImmutableArray类型会有所帮助两个具有相同内容的不可变数组,不同内容,不同的可变数组相互不相等是完全正确和恰当的。

#1


5  

Although Microsoft's Framework classes are unfortunately a bit inconsistent with regard to what Object.Equals(Object) means, in general X.Equals(Y) will only be true if replacing arbitrary references to X with references to Y, and/or vice versa, would not be expected to alter the semantics of the objects in question. For example, if X is a String with the content "Hello", and Y is a different string with that same content, replacing references to one string with references to the other would not generally alter their behavior. Although code which uses ReferenceEquals to test whether two string references refer to the same string might notice the switch, normal string code would not.

尽管微软的Framework类在Object.Equals(Object)的含义方面有点不一致,但一般来说X.Equals(Y)只有在用Y引用替换X的任意引用时才会为真,反之亦然,不会期望改变有问题的对象的语义。例如,如果X是具有内容“Hello”的字符串,并且Y是具有相同内容的不同字符串,则将对一个字符串的引用替换为对另一个字符串的引用通常不会改变它们的行为。虽然使用ReferenceEquals测试两个字符串引用是否引用相同字符串的代码可能会注意到该开关,但普通字符串代码不会。

As a general rule, no mutable object is equivalent to any other, and thus no reference to a mutable object should be equivalent to another unless both references refer to the same object. There is a big difference between having references to two different instances of int[], both of which hold the same values, versus having two references to the same instance. While it would be helpful for Array to have ItemsEqual methods which would test whether all items of the arrays, or certain ranges of items, matched, and it would be helpful to have an ImmutableArray type with a Equals/GetHashCode members that would regard as equal two immutable arrays with the same content, it is entirely right and proper that distinct mutable arrays compare unequal to each other regardless of content.

作为一般规则,任何可变对象都不等同于任何其他对象,因此除非两个引用引用同一对象,否则对可变对象的引用应该等同于另一个。对两个不同的int []实例的引用之间存在很大差异,两个实例都具有相同的值,而对同一个实例有两个引用。虽然使用ItemsEqual方法来测试数组中的所有项目或某些项目范围是否匹配会有所帮助,但是使用具有Equals / GetHashCode成员的ImmutableArray类型会有所帮助两个具有相同内容的不可变数组,不同内容,不同的可变数组相互不相等是完全正确和恰当的。