Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why SequenceEqual for List<T> returns false?

Hi I have some problems with sequenceEqual when I have situation like this:

Sentence s1 = new Sentence { Text = "Hi", Order = 1 };
Sentence s2 = new Sentence { Text = "Hello", Order = 2 };
List<Sentence> list1 = new List<Sentence> { s1, s2 };
List<Sentence> list2 = new List<Sentence> { s1, s2 };

and this works fine

bool equal = list1.SequenceEqual(list2);

and returns true;

but when I have some method which returns List<Sentence> for example:

public List<Sentence> Getall()
    {
        Sentence s1 = new Sentence { Text = "Hi", Order = 1 };
        Sentence s2 = new Sentence { Text = "Hello", Order = 2 };

        return new List<Sentence> { s1, s2 };
    }

and use it like this:

List<Sentence> list1 = Getall();
List<Sentence> list2 = Getall();

and then simply, check it

bool equal = list1.SequenceEqual(list2);

it returns 'false', please tell me why? and how to make it work?

like image 863
Tomasz Kowalczyk Avatar asked Feb 19 '13 12:02

Tomasz Kowalczyk


People also ask

What is the use of SequenceEqual in C#?

The SequenceEqual<TSource>(IEnumerable<TSource>, IEnumerable<TSource>) method enumerates the two source sequences in parallel and compares corresponding elements by using the default equality comparer for TSource , Default. The default equality comparer, Default, is used to compare values of the types.

How do I check if a list is equal C#?

Equals(Object) Method which is inherited from the Object class is used to check if a specified List<T> object is equal to another List<T> object or not. Syntax: public virtual bool Equals (object obj); Here, obj is the object which is to be compared with the current object.


3 Answers

Your problem is that one new Sentence { Text = "Hi", Order = 1 } is not equal to another new Sentence { Text = "Hi", Order = 1 }. Although the contents are the same, you have two separate objects, and unless you've designed your class otherwise they are not equal to each other unless they are literally the same objects (as in your first example).

Your Sentence class needs to override Equals and GetHashCode, at the very least, at which point your SequenceEquals should work again.

like image 91
Rawling Avatar answered Oct 21 '22 00:10

Rawling


As the MSDN states here:

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

Sentence in your case is a reference type with default Equals and GetHashCode, which means it will be using referential equality for each element.

You can always use the overload which accepts IEqualityComparer

like image 41
Patryk Ćwiek Avatar answered Oct 21 '22 01:10

Patryk Ćwiek


You are creating two new instances of Sentence every time you call Getall(). When comparing the elements in the list, SequenceEqual will use the default equality comparer, which basically just check that they refer to the same object: they don't, so they are different.

What you can do is override the Equal() and == operators in Sequence to have equality check other properties (like Text and Order).

Alternatively you can write an IEqualityComparer<Sequence> and pass it to SequenceEqual

like image 36
Tallmaris Avatar answered Oct 21 '22 01:10

Tallmaris