views:

456

answers:

4

There are many ways to do this but I feel like I've missed a function or something.

Obviously List == List will use Object.Equals() and return false.

If every element of the list is equal and present in the same location in the opposite list then I would consider them to be equal. I'm using value types, but a correctly implemented Data object should work in the same fashion (i.e I'm not looking for a shallow copied list, only that the value of each object within is the same).

I've tried searching and there are similar questions, but my question is an equality of every element, in an exact order.

+6  A: 
SequenceEqual
leppie
using System.Linq;Will that throw if the sequences are of differing length or they are out of order etc?
Spence
This method asks a question, so it shouldn't provide the answer by throwing. The only reason it should throw is if either of the sequences is a null reference.
Daniel Earwicker
sorry asked too quickly. Will it return false if the sequences are of different length or out of order?
Spence
@Spence - Yes, SequenceEqual returns false when the sequences are different lengths or out-of-order: http://msdn.microsoft.com/en-us/library/bb348567.aspx
LukeH
@Luke, out of order was not asked.
leppie
@leppie - I wasn't disputing your answer (+1 from me already). I was just confirming what Spence asked in his comment above.
LukeH
yeah the new show more comments bit is annoying, you can miss the context of the comments. cheers for your help guys. Shame that my objects don't implement IEquatable :(
Spence
A: 

Evil implementation is

if (List1.Count == List2.Count)
{
   for(int i = 0; i < List1.Count; i++)
   {
      if(List1[i] != List2[i])
      {
         return false;
      }
   }
   return true;
}
return false;
Spence
This is almost exactly how the built-in SequenceEqual method works, as in leppie's answer. (Your version will return slightly faster than SequenceEqual if the collections have different lengths but it's restricted to IList<T>, whereas SequenceEqual will work with any IEnumerable<T>.)
LukeH
A: 

I knocked up a quick extension method:

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static bool Matches<T>(this List<T> list1, List<T> list2)
        {
            if (list1.Count != list2.Count) return false;
            for (var i = 0; i < list1.Count; i++)
            {
                if (list1[i] != list2[i]) return false;
            }
            return true;
        }
    }   
}
Luke Schafer
+1  A: 

I put together this variation:

private bool AreEqual<T>(List<T> x, List<T> y)
{
    // same list or both are null
    if (x == y)
    {
        return true;
    }

    // one is null (but not the other)
    if (x== null || y == null)
    {
        return false;
    }

    // count differs; they are not equal
    if (x.Count != y.Count)
    {
        return false;
    }

    for (int i = 0; i < x.Count; i++)
    {
        if (!x[i].Equals(y[i]))
        {
            return false;
        }
    }
    return true;
}

The nerd in me also crawled out so I did a performance test against SequenceEquals, and this one has a slight edge.

Now, the question to ask; is this tiny, almost measurable performance gain worth adding the code to the code base and maintaining it? I very much doubt it ;o)

Fredrik Mörk