【问题标题】:Comparing 2 lists with different references (C#)比较具有不同引用的 2 个列表 (C#)
【发布时间】:2011-04-15 23:32:32
【问题描述】:

基本上,我有一个包含许多字段的结构。我将创建两个包含此结构实例的列表,并且我需要能够检查两个列表是否相同(即,相同数量的结构并且所有字段具有相同的值)。

我正在研究 SequenceEqual 运算符,但这依赖于列表中具有相同 reference 的项目 - 它们不会,它们都来自不同的来源。

我可以按一个字段对列表进行排序,遍历列表中的每个项目,然后遍历列表中的每个字段/属性,看看它是否与另一个列表匹配——但这似乎有点过于复杂。有没有更简单的方法?

【问题讨论】:

    标签: c# linq list


    【解决方案1】:

    SequenceEqual 运算符使用比较器进行比较,而不是通过引用序列。

    来自MSDN:“通过使用其类型的默认相等比较器比较元素来确定两个序列是否相等。”

    使用SequenceEqual 并实现IEqualityComparer 应该没问题。

    var areSame = list1.SequenceEqual(list2, new MyStructComparer());
    
    class MyStructComparer : IEqualityComparer<MyStruct> {
        public bool Equals(MyStruct x, MyStruct y) {
            if (Object.ReferenceEquals(x, y)) 
                return true;
            if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
                return false;
            return x.A == y.A && x.B == y.B;
        }
    
        public int GetHashCode(MyStruct myStruct)
        {        
            if (Object.ReferenceEquals(myStruct, null)) 
                return 0;
    
            int hashMyStructA = myStruct.A == null ? 0 : myStruct.A.GetHashCode();
            int hashMyStructB = myStruct.B == null ? 0 : myStruct.B.GetHashCode();
    
            return hashMyStructA ^ hashMyStructB;
        }   
    }
    

    【讨论】:

    • 这意味着他仍然需要在结构上提供自己的Equals() 方法。他可以逃脱使用签名first.All(i =&gt; second.Any(x =&gt; x.Id.equals(i.Id)));
    • 这不是真的,他可以将IEqualityComparer 传递给可以处理比较的SequenceEqual 方法。结构可以保持愉快地不知道。
    【解决方案2】:

    您可以覆盖Equals() 并比较其中的所有属性,如果它们都相等则返回true。

        public struct MyStruct
        {
    
            public int A;
            public int B;
    
            public override bool Equals(object obj)
            {
                MyStruct other = (MyStruct) obj;
                return A == other.A && B == other.B;
            }
        }
    

    为了列表的相等性,我会写一个扩展方法:

        public static class MyStructExtension
        {
            public static bool ListsEqual(this IList<MyStruct> a, IList<MyStruct> b)
            {
                if(a==b)
                    return true;
                if (a == null || b == null)
                    return false;
                if (a.Count != b.Count)
                    return false;
                for (int i = 0; i < a.Count; i++)
                {
                    if (!a[i].Equals(b[i]))
                        return false;
                }
    
                return true;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多