我有2个阵列:
int[] arr1 = new int[] { 1, 2, 3 };
int[] arr2 = new int[] { 1, 2, 3 };
我需要检查它们是否相等(不是参考)
写作之间有什么区别:
Console.WriteLine(arr1.SequenceEqual(arr2)); //true
VS
IStructuralEquatable eqArray1 = arr1;
Console.WriteLine(eqArray1.Equals(arr2, StructuralComparisons.StructuralEqualityComparer)); //true
都返回True ..
我应该何时使用?
答案 0 :(得分:2)
我刚才有一个相关的问题,看到这个问题从来没有得到真正的回答。结构和序列之间存在差异 - 第一个比较深,第二个比较不。
这个简单的代码演示并生成True
False
:
int[][] ints1 = { new int[] { 3, 4 } };
int[][] ints2 = { new int[] { 3, 4 } };
Console.WriteLine(StructuralComparisons.
StructuralEqualityComparer.Equals(ints1, ints2));
Console.WriteLine(ints1.SequenceEqual(ints2));
名称“序列”表示一维主义,因此名称选择是恰当的。
答案 1 :(得分:1)
.NET中的标准相等性检查使用EqualityComparer.Default进行比较。例如,您编写的字典或SequenceEqual方法默认使用EqualityComparer.Default。并且该比较器在IEquatable接口实现的情况下使用Equals(object)方法或Equals(T)方法。
但是你总是可以给像StructuralComparisons.StructuralEqualityComparer这样的其他比较器提供字典或方法,比如SequenceEqual。
因此,两种方法的主要区别在于它们使用的等式检查方法。 SequenceEqual使用IEquatable接口方法进行检查,而StructuralComparisons.StructuralEqualityComparer使用IStructuralEquatable接口方法进行检查。因此,默认的相等检查需要两个比较的项目是相同的类型,但StructuralEqualityComparer不要求它们是相同的类型。顾名思义它应该比较内容。
答案 2 :(得分:1)
SequenceEqual
的实现有点类似::
using (IEnumerator<TSource> enumerator1 = first.GetEnumerator())
using (IEnumerator<TSource> enumerator2 = second.GetEnumerator())
{
while (enumerator1.MoveNext())
{
if (!enumerator2.MoveNext() || !comparer.Equals(enumerator1.Current, enumerator2.Current))
{
return false;
}
}
if (enumerator2.MoveNext())
{
return false;
}
}
return true;
此默认SequenceEqual
方法使用EqualityComparer<int>.Default
的默认int
,这是值相等。
Array
使用IStructuralEquatable
方法实施Equal
:
bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
{
if (other == null) return false;
if (!object.ReferenceEquals(this, other))
{
Array array = other as Array;
if ((array == null) || (array.Length != this.Length))
{
return false;
}
for (int i = 0; i < array.Length; i++)
{
object x = this.GetValue(i);
object y = array.GetValue(i);
if (!comparer.Equals(x, y))
{
return false;
}
}
}
return true;
}
使用输入参数中的IEqualityComparer
,此处输入StructruralEqualityComparer
但int
未实现IStructruralEquatable
,因此它使用int
的默认比较器这是价值平等。
但是,由于StructruralEqualityComparer
不是结构性的,因此无需输入int
,您应该使用:
(arr1 as IStructuralEquatable).Equals(arr2, EqualityComparer<int>.Default);
它仍然有效。如果数组中的项目是 structrural
,则应使用StructruralEqualityComparer
总而言之,两者的实现是相同的,都基于int
的值相等来迭代两个数组以进行比较。
我更喜欢LINQ版本,因为它更具可读性。
答案 3 :(得分:0)
linq版本最灵活,它可以比较两个枚举 StructuralComparisons.StructuralEqualityComparer版本要求两个集合可以支持IStructuralEquatable接口。但如果两个列表的长度不均匀,我希望后者更快。
答案 4 :(得分:-1)
我认为System.Linq是你的朋友:
bool isEqual = Enumerable.SequenceEqual(array1, array2);