Enumerable.Except returns distinct items

This one took me by sur­prise a lit­tle but there’s some­thing about the Enumerable.Except method which you ought to know about. At first you might have assumed (as I did) that giv­en an array as the base set and call­ing the Except exten­sion method with a sec­ond array will return all the items in the first array which do not appear in the sec­ond array.

Well, not exact­ly, for instance:

var list1 = new[] { 1, 1, 1, 1 };
var list2 = Enumerable.Empty<int>();

var result = list1.Except(list2); // returns { 1 } instead of the expected { 1, 1, 1, 1 }

var list3 = new[] { 1, 1, 2, 2, 3 };
var list4 = new[] { 1 };

var result2 = list3.Except(list4); // returns { 2, 3 } instead of the expected { 2, 2, 3 }

Does it sur­prise you that only dis­tance instances of the orig­i­nal array is returned by the Except method? Whilst I haven’t found any offi­cial Microsoft documentation/article on why Except behaves in this way, the best expla­na­tion I have heard so far is that Except per­forms a set oper­a­tion, accord­ing to MSDN:

Pro­duces the set dif­fer­ence of two sequences by using the default equal­i­ty com­par­er to com­pare val­ues.

And a Set in the math­e­mat­i­cal sense is defined as:

A set is a col­lec­tion of dis­tinct objects, con­sid­ered as an object in its own right