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 and Y refer to the same object X.Equals(Y) and X.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, but X.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) and X.SequenceEquals(Y) will be false. If changes are made to one or both lists, X.SequenceEquals(Y) may become true, but X.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.