在 C#
中,为什么 Equals()
方法总是通过比较引用而不是比较内容来检查两个 数组
之间的相等性?
因此,所有在其实现中调用 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
处理数组(无论类型如何)的一种可能的通用方法可能是:
在 Object.Equals()
中:如果要比较的两种类型都是数组(长度相同),枚举项目(总是可能的),对于每个项目,调用 Equals()
。如果这些调用之一返回 false
,则数组不同(返回 false
),否则返回 true
。
注意:我知道 SequenceEqual()
、memcmp()
和其他比较两个数组的方法。我的问题不是关于如何比较数组。我只是想知道为什么 C#
设计者不选择在 Equals()
方法中实现完整的数组比较。
最佳答案
虽然 Microsoft 的框架类在 Object.Equals(Object)
的含义方面不幸有点不一致,但通常 X.Equals(Y)
只会为真如果将对 X
的任意引用替换为对 Y
的引用,和/或相反,则不会改变相关对象的语义。例如,如果 X
是内容为“Hello”的 String
,而 Y
是具有相同内容的不同字符串,替换对一个字符串引用另一个字符串通常不会改变它们的行为。虽然使用 ReferenceEquals
来测试两个字符串引用是否引用同一个字符串的代码可能会注意到这个开关,但普通的字符串代码不会。
作为一般规则,没有可变对象等同于任何其他对象,因此对可变对象的引用不应等同于另一个,除非两个引用都引用相同对象。对 int[]
的两个不同实例(它们都具有相同的值)的引用与对同一实例的两个引用之间存在很大差异。虽然 Array
有 ItemsEqual
方法会很有帮助,该方法可以测试数组的所有项目或某些范围的项目是否匹配,并且有帮助具有 Equals
/GetHashCode
成员的 ImmutableArray
类型将被视为相等的两个具有相同内容的不可变数组,这是完全正确和正确的无论内容如何,不同的可变数组都相互比较不相等。
关于c# - 在 C# 中,为什么数组上的 Equals() 方法只比较它们的引用,而不是它们的实际内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14960191/