Сравнение 2 списков с разными ссылками (C #)

#c# #linq #list

#c# #linq #Список

Вопрос:

В принципе, у меня есть структура, которая содержит несколько полей. Я собираюсь создать два списка, содержащих экземпляры этой структуры, и мне нужно иметь возможность проверить, идентичны ли оба списка (т. Е. Одинаковое количество структур и одинаковые значения для всех полей).

Я изучал оператор SequenceEqual, но это зависит от элементов в списке, имеющих одну и ту же ссылку — они не будут, они оба поступают из разных источников.

Я мог бы просто упорядочить списки по полю, перебрать каждый элемент в списке, затем перебрать каждое поле / свойство в списке и посмотреть, совпадает ли оно в другом списке — но это кажется немного чрезмерно сложным. Есть ли более простой способ?

Ответ №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 amp;amp; 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;
    }   
}
  

Комментарии:

1. Это означает, что ему все еще нужно предоставить свой собственный Equals() метод в структуре. Ему могло сойти с рук usign first.All(i => second.Any(x => x.Id.equals(i.Id)));

2. Это неверно, он мог бы передать 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 amp;amp; 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;
        }
    }