2

I used to compare lists like this, but it returns false in a test:

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

And tried converting to json and it worked:

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

Values seems to be equal, what could be different? How to find out what is different in the lists?

Updated:

My class:

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

    public override string ToString()
    {
        return Id.ToString();
    }
}
i3arnon
  • 113,022
  • 33
  • 324
  • 344
1gn1ter
  • 1,414
  • 2
  • 22
  • 47
  • 1
    You need to check that sequences just contains the same elements, or also in the same order? – abatishchev Dec 07 '11 at 12:56
  • 1
    Try [C# compare two Lists for differences](http://stackoverflow.com/questions/675699/c-sharp-compare-two-lists-for-differences) – Michał Powaga Dec 07 '11 at 12:56
  • i need to compare only values. But it is interesting: why while values of objects are equal, the order in the list is equal, SequenceEquals returns false. – 1gn1ter Dec 07 '11 at 13:01
  • @1gn1ter: What `T` does your lists contain? – abatishchev Dec 07 '11 at 13:02
  • 1
    @1gn1ter: `Enumerable.SequenceEqual()` uses `EqualityComparer.Default` to compare items, that may be the cause. – abatishchev Dec 07 '11 at 13:03
  • I've tried: Assert.IsTrue(new HashSet(expected).SetEquals(actual)); and Enumerable.SequenceEqual() and they return false. – 1gn1ter Dec 07 '11 at 13:10
  • 2
    The reason is that your comparer is comparing the references to your objects, NOT the values. You'll need to override Equals (etc) to get the desired functionality. Or, you can do a field by field comparison. – Bob2Chiv Dec 07 '11 at 13:31

4 Answers4

5

If MyClass implements IEquatable<MyClass>, then try this:

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

If it does not implement IEquatable then you could expect strange behavior, since the object references will be compared in the two lists, and not their fields:

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));
  }
}

Output:

False
True
True
False
kol
  • 27,881
  • 12
  • 83
  • 120
3
using System.Linq;

Enumerable.SequenceEqual(a, b);

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

See MSDN, also this question.

Community
  • 1
  • 1
abatishchev
  • 98,240
  • 88
  • 296
  • 433
0

Perhaps you can use IEnumerable.ExceptOf

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

Our perhaps you can use an HashSet and there the intersect method. http://msdn.microsoft.com/en-us/library/bb293080.aspx

Boas Enkler
  • 12,264
  • 16
  • 69
  • 143
  • Except method also, gives that objects are different. while the values of objects are the same. – 1gn1ter Dec 07 '11 at 13:02
0

I tend to find the HashSet<T> collection fit for this kind of purpose, cast your collections into HashSet<T> then call SetEquals

Louis Kottmann
  • 16,268
  • 4
  • 64
  • 88