如何比较 C # 中的数组?

可能的复制品:
比较 C # 中数组的最简单方法

如何比较 C # 中的两个数组?

我使用下面的代码,但它的结果是假的。

Array.Equals(childe1,grandFatherNode);
173589 次浏览

您正在比较 对象引用,它们并不相同。您需要比较数组内容。

. NET2解决方案

一个选项遍历数组元素,并对每个元素调用 Equals()。请记住,如果数组元素不是相同的对象引用,则需要重写数组元素的 Equals()方法。

另一种方法是使用这种通用方法来比较两个通用数组:

static bool ArraysEqual<T>(T[] a1, T[] a2)
{
if (ReferenceEquals(a1, a2))
return true;


if (a1 == null || a2 == null)
return false;


if (a1.Length != a2.Length)
return false;


var comparer = EqualityComparer<T>.Default;
for (int i = 0; i < a1.Length; i++)
{
if (!comparer.Equals(a1[i], a2[i])) return false;
}
return true;
}

NET 3.5或更高版本的解决方案

如果 Linq 可用,则使用 顺序相等(. NET Framework > = 3.5)

Equals方法做一个引用比较-如果数组是 与众不同对象,这将返回 false。

要检查数组是否包含相同的值(顺序相同) ,需要对它们进行迭代,并对每个值进行相等性测试。

Array.Equals比较的是参考文献,而不是内容:

目前,当您将两个数组与 = 运算符进行比较时,我们实际上使用的是 System。对象的 = 运算符,它只比较实例。(也就是说,它使用引用相等性,所以只有当两个数组指向完全相同的实例时,它才为真)

来源

如果要比较数组的 内容,则需要遍历数组并比较元素。

同一篇博客文章中有如何做到这一点的例子。基本的实现方法是:

public static bool ArrayEquals<T>(T[] a, T[] b)
{
if (a.Length != b.Length)
{
return false;
}


for (int i = 0; i < a.Length; i++)
{
if (!a[i].Equals(b[i]))
{
return false;
}
}


return true;
}

尽管这会带来性能问题。添加一个约束:

public static bool ArrayEquals<T>(T[] a, T[] b) where T: IEquatable<T>

将会改进一些东西,但是这意味着代码只能与实现 IEquatable的类型一起工作。

使用 EqualityComparer。默认的 Equals 方法而不是对类型本身调用 Equals 也将提高性能,而不需要类型实现 IEquatable。在这种情况下,方法的主体变成:

    EqualityComparer<T> comparer = EqualityComparer<T>.Default;


for (int i = 0; i < a.Length; i++)
{
if (!comparer.Equals(a[i], b[i]))
{
return false;
}
}

Equals ()似乎只测试同一个实例。

似乎没有一种方法可以比较这些值,但是它很容易编写。

只要比较长度,如果不相等,返回 false。否则,循环遍历数组中的每个值并确定它们是否匹配。

Array类中没有静态 Equals方法,所以实际上使用的是 Object.Equals,它确定两个对象引用是否指向同一个对象。

如果要检查数组是否包含相同顺序的项,可以使用 SequenceEquals扩展方法:

childe1.SequenceEqual(grandFatherNode)

编辑:

若要将 SequenceEquals与多维数组一起使用,可以使用扩展来枚举它们。下面是枚举二维数组的扩展:

public static IEnumerable<T> Flatten<T>(this T[,] items) {
for (int i = 0; i < items.GetLength(0); i++)
for (int j = 0; j < items.GetLength(1); j++)
yield return items[i, j];
}

用法:

childe1.Flatten().SequenceEqual(grandFatherNode.Flatten())

如果数组的维数超过两个,则需要一个支持该维数的扩展。如果维数不同,则需要更复杂的代码来循环维数可变的数目。

当然,在比较数组的内容之前,首先要确保数组的维数和维数的大小匹配。

编辑2:

结果是,您可以使用 OfType<T>方法来压平数组,正如 RobertS 指出的那样。当然,只有当所有的项实际上都可以强制转换为相同的类型时,这种方法才有效,但是如果您可以对它们进行比较,情况通常就是这样。例如:

childe1.OfType<Person>().SequenceEqual(grandFatherNode.OfType<Person>())

您可以使用 System.Linq 中的 Enumable.Sequenceequals ()来比较数组中的内容

bool isEqual = Enumerable.SequenceEqual(target1, target2);