Chris
Chris

Reputation: 7611

Comparing 2 lists with different references (C#)

Basically, I have a struct which contains a number of fields. I'm going to be creating two lists containing instances of this struct, and I need to be able to check to see if both lists are identical (i.e., same number of structs and have the same values for all of the fields).

I was looking into the SequenceEqual operator, but that relies on the items in the list having the same reference - they won't, they're both coming from different sources.

I could just order the lists by a field, loop through each item in the list, then loop through each field/property in the list and see if it matches in the other list - but it seems a bit overcomplicated. Is there an easier way?

Upvotes: 0

Views: 308

Answers (2)

Mikael Östberg
Mikael Östberg

Reputation: 17156

The SequenceEqual operator compares using a comparer and not by reference of the sequences.

From MSDN: "Determines whether two sequences are equal by comparing the elements by using the default equality comparer for their type."

Use the SequenceEqual and implement a IEqualityComparer and you should be fine.

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

Upvotes: 4

Aliostad
Aliostad

Reputation: 81660

You can override Equals() and compare all the properties in there and return true if they are all equal.

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

For equality of the lists, I would write an extension method:

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

Upvotes: 1

Related Questions