Сравнение двух списков <MyClass>: как узнать разницу? - PullRequest
2 голосов
/ 07 декабря 2011

Раньше я сравнивал списки вот так, но в тесте возвращается false:

Assert.IsTrue(expected.SequenceEquals(actual));

И попытался преобразовать в JSON, и это сработало:

Assert.AreEqual(expected.ToJson(), actual.ToJson());

Значения кажутся равными, что может быть другим? Как узнать, что отличается в списках?

Обновлено:

Мой класс:

public class Department
{
    [BsonId]
    public ObjectId Id { get; set; }    
    public string Name { get; set; }            

    public override string ToString()
    {
        return Id.ToString();
    }
}

Ответы [ 4 ]

5 голосов
/ 07 декабря 2011

Если MyClass реализует IEquatable<MyClass>, попробуйте следующее:

expected.Sort(); 
actual.Sort();
if (Enumerable.SequenceEqual(actual, expected)) { ... }

Если он не реализует IEquatable, вы можете ожидать странного поведения, поскольку ссылки на объекты будут сравниваться в двух списках, а не в их полях:

using System;
using System.Collections.Generic;
using System.Linq;

public class MyClassA
{
  private int i;
  public MyClassA(int i) { this.i = i; }
}

public class MyClassB : IEquatable<MyClassB>
{
  private int i;
  public MyClassB(int i) { this.i = i; }
  public bool Equals(MyClassB other) { return this.i == other.i; }
}

public class Program
{
  public static void Main()
  {
    var actual1 = new List<MyClassA>() { new MyClassA(1), new MyClassA(2), new MyClassA(3) };
    var expected1 = new List<MyClassA>() { new MyClassA(1), new MyClassA(2), new MyClassA(3) };
    Console.WriteLine(Enumerable.SequenceEqual(actual1, expected1));

    var a1 = new MyClassA(1);
    var a2 = new MyClassA(2);
    var a3 = new MyClassA(3);
    var actual2 = new List<MyClassA>() { a1, a2, a3 };
    var expected2 = new List<MyClassA>() { a1, a2, a3 };
    Console.WriteLine(Enumerable.SequenceEqual(actual2, expected2));

    var actual3 = new List<MyClassB>() { new MyClassB(1), new MyClassB(2), new MyClassB(3) };
    var expected3 = new List<MyClassB>() { new MyClassB(1), new MyClassB(2), new MyClassB(3) };
    Console.WriteLine(Enumerable.SequenceEqual(actual3, expected3));

    var actual4 = new List<MyClassB>() { new MyClassB(1), new MyClassB(2), new MyClassB(3) };
    var expected4 = new List<MyClassB>() { new MyClassB(3), new MyClassB(2), new MyClassB(1) };
    Console.WriteLine(Enumerable.SequenceEqual(actual4, expected4));
  }
}

Выход:

False
True
True
False
3 голосов
/ 07 декабря 2011
using System.Linq;

Enumerable.SequenceEqual(a, b);

// or SequenceEqual(a, b, StringComparer.OrdinalIgnoreCase)

См. MSDN , также этот вопрос .

0 голосов
/ 07 декабря 2011

Я склонен найти коллекцию HashSet<T>, подходящую для такого рода целей, приведите ваши коллекции в HashSet<T>, затем позвоните SetEquals

0 голосов
/ 07 декабря 2011

Возможно, вы можете использовать IEnumerable.ExceptOf

http://msdn.microsoft.com/en-us/library/bb300779.aspx

Наш, возможно, вы можете использовать HashSet и там метод пересечения. http://msdn.microsoft.com/en-us/library/bb293080.aspx

...