在 C# 中,为什么数组上的 Equals() 方法只比较它们的引用,而不是它们的实际内容 [英] In C#, why Equals() method on arrays only compare their references, not their actual content

查看:19
本文介绍了在 C# 中,为什么数组上的 Equals() 方法只比较它们的引用,而不是它们的实际内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

因此,所有在其实现中调用 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) :

示例:

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 :

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

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.

注意:我知道 SequenceEqual()memcmp() 和其他比较两个数组的方法.我的问题不是关于如何比较数组.我只是想知道为什么 C# 设计者不选择在 Equals() 方法中实现全数组比较.

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.

推荐答案

尽管遗憾的是 Microsoft 的 Framework 类在 Object.Equals(Object) 的含义方面有点不一致,但总的来说 X.Equals(Y) 仅在用对 Y 的引用替换对 X 的任意引用时才为真,反之亦然改变所讨论对象的语义.例如,如果 X 是内容为Hello"的 String,而 Y 是具有相同内容的不同字符串,则替换对一个字符串引用另一个字符串通常不会改变它们的行为.虽然使用 ReferenceEquals 来测试两个字符串引用是否指向同一个字符串的代码可能会注意到切换,但正常的字符串代码不会.

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.

作为一般规则,任何可变对象都不等同于任何其他对象,因此对可变对象的引用不应与另一个等效,除非两个引用都引用相同对象.对 int[] 的两个不同实例的引用与对同一个实例有两个引用之间存在很大差异,这两个实例具有相同的值.虽然 ArrayItemsEqual 方法可以测试数组的所有项目或某些项目范围是否匹配会很有帮助,但拥有一个带有 Equals/GetHashCode 成员的 ImmutableArray 类型会认为两个具有相同内容的不可变数组相等,这是完全正确和适当的无论内容如何,​​不同的可变数组都彼此不相等.

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.

这篇关于在 C# 中,为什么数组上的 Equals() 方法只比较它们的引用,而不是它们的实际内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆