Difference between “Equals” and “SequenceEqual”?
In general, Equals
is supposed to represent a "permanent" equivalence relation. If the object referred to by X
reports that it Equals
the object referred to by Y, then the former object should always report that it Equals
the latter. Generally, mutable objects will not report themselves as equivalent to anything but themselves because even if the state of a mutable object matches that of another at some moment in time, there's no guarantee that it will always do so.
SequenceEqual, by contrast, represents a transitory condition. All it indicates is whether, at the time it is called, enumeration of both objects will report the same sequence of items. It makes no other promise about the past, present, or future state of the objects.
If all objects are of type List<string>
, Equals
and SequenceEqual
will test test the following conditions:
If
X
andY
refer to the same objectX.Equals(Y)
andX.SequenceEqual(Y)
will both be true as long as those references exist and neither is made to point to another object.If they refer to different lists containing the same items,
X.Equals(Y)
will be false, butX.SequenceEqual(Y)
will be true; note that if changes are made to one or both lists,X.SequenceEqual(Y)
may become false.If they refer to different lists containing different items, both
X.Equals(Y)
andX.SequenceEquals(Y)
will be false. If changes are made to one or both lists,X.SequenceEquals(Y)
may become true, butX.Equals(Y)
cannot.
Unless a list is used in thread-unsafe fashion (in which case all bets are off), or one has a list of objects which don't obey the standard Equals
contract, there is no way that X.Equals(Y)
can be true but X.SequenceEquals(Y)
false.
For 2nd part of question as first has been answered by @Daniel:
Equals(obj1, obj2) and obj1.Equals(obj2)
obj1.Equals(obj2) is instance method of object and it will throw exception if obj1 is null. Where as Equals(obj1,obj2) is static method and will work if you obj1 is null. You can also override Euqals for a class
object obj1 = new object();
object obj2 = new object();
Console.WriteLine(obj1.Equals(obj2)); //print false
obj1 = null;
Console.WriteLine(obj1.Equals(obj2)); // will throw exception
Console.WriteLine(Equals(obj1, obj2));// return false in this case and since its static it will not throw the exception
Equals
returns true
only if MyList1
and MyList2
are the same instance.SequenceEqual
returns true
if both lists contain the same items.
Example:
var list1 = new List<int> { 1, 2, 3 };
var list2 = new List<int> { 1, 2, 3 };
var list3 = list1;
var list4 = new List<int> { 1, 2, 3, 4 };
Equals(list1, list2) == false
list1.SequenceEqual(list2) == true
Equals(list1, list3) == true
list1.SequenceEqual(list3) == true
Equals(list1, list4) == false
list1.SequenceEqual(list4) == false
The difference between Equals(obj1, obj2)
and obj1.Equals(obj2)
is that the first one uses the static method Object.Equals
and the second uses the instance method Equals
. The result of these two calls will differ, if the class of obj1
overrides Object.Equals
.