【问题标题】:Compare Arrays in C# using SequenceEqual在 C# 中使用 SequenceEqual 比较数组
【发布时间】:2021-09-10 12:09:33
【问题描述】:

我正在尝试比较 C# 中的两个数组,如上一篇 SO 帖子中所述:

为什么以下对我不起作用:

var first = Value as Array;
var second = other.Value as Array;
bool equal = first.SequenceEqual(second);

我明白了:

CS1061:“Array”不包含“SequenceEqual”的定义和 没有可访问的扩展方法“数组”接受第一个参数 可以找到类型“数组”(您是否缺少 using 指令或 程序集参考?)。

我确实有权在顶部使用:

using System.Linq;

因为我会写(没有编译器错误):

var first = Value as string[];
var second = other.Value as string[];
bool equal = first.SequenceEqual(second);

作为参考,我正在尝试为通用值类型实现 Equals 运算符:

public struct MyValue<T> : IEquatable<MyValue<T>> 
{
  public T Value { get; set; }
  public bool Equals(VRValue<T> other) => throw new NotImplementedException();
}

【问题讨论】:

  • Array 实现了IEnumerable,但SequenceEqual 仅为IEnumerable&lt;T&gt; 定义
  • 与其检查Array,更好的方法是检查IStructuralEquatable,这是Array(和其他一些集合)实现的。
  • 您可以通过转换其元素来使用带有Array 的 Linq,例如bool equal = first.Cast&lt;object&gt;().SequenceEqual(second.Cast&lt;object&gt;());

标签: c# arrays linq generics equality


【解决方案1】:

SequenceEqualIEnumerable&lt;T&gt; 一起使用,但Array 仅实现非泛型IEnumerable,因此SequenceEqual 不适用于此处。

当转换为 string[] 时,您会得到不同(类型化)类型的数组,它完全实现了 IEnumerable&lt;T&gt;(其中 T 是此示例的字符串)

【讨论】:

    【解决方案2】:

    使用@Sweeper/@Jeppe Stig Nielsen 的建议,我将函数重写为:

    public bool Equals(VRValue<T> other)
    {
        if (typeof(T).IsArray)
        {
            var first = Value as IStructuralEquatable;
            var second = other.Value as IStructuralEquatable;
            return StructuralComparisons.StructuralEqualityComparer.Equals(first, second);
        }
      [...]
    }
    

    使用HashSet时,还要注意GetHashCode:

    public override int GetHashCode()
    {
        if (typeof(T).IsArray)
        {
            var first = Value as IStructuralEquatable;
            return StructuralComparisons.StructuralEqualityComparer.GetHashCode(first);
        }
        [...]
    }
    

    【讨论】:

    • 考虑return StructuralComparisons.StructuralEqualityComparer.Equals(first, second);。 (您现在所拥有的只是检查相同性(即引用相等性),因此它等效于return first == second;,如果两个操作数是具有相同长度和相同条目的不同数组,则它会说 false。)
    • 对于“获取哈希码”,您必须使用相关方法,而不仅仅是其他方法!所以当然return StructuralComparisons.StructuralEqualityComparer.GetHashCode(first); 既然你遵循了我在第一条评论中的建议。哈希码应该与使用的Equals 匹配,否则一切都是无稽之谈。 EqualityComparer&lt;object&gt;.Default 在你的情况下真的错了。
    猜你喜欢
    • 2021-08-16
    • 1970-01-01
    • 2021-11-28
    • 2010-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多