In C Sharp .NET there is a Equals
method and a SetEquals
method. Where is the difference?
Coming from Java, my first thought was that SetEquals
is not necessary, just use the Equals
method for all objects.
SetEquals
doesn't obey the same contract as Equals
. In particular it's not symmetric, as the argument is just IEnumerable<T>
rather than ISet<T>
. This allows you to check for set equality while only having one set. Consider:
List<int> intList = new List<int> { 1, 2, 3 };
HashSet<int> intSet = new HashSet<int>(intList);
Now we can use:
Console.WriteLine(intSet.SetEquals(intList));
... but we couldn't implement Equals
in the same way without enforcing the same behaviour on List<int>
and every other IEnumerable<T>
implementation.
Even if we restricted it to other sets, there's the interesting question of what equality really means. For example, consider two HashSet<string>
sets which contain the same strings, but have different equality comparers. (Maybe one is case-sensitive and one isn't.) Are those equal, or not? SetEquals
manages to avoid such philosophical questions by avoiding trying to be too general.
What about a HashSet<int>
and a SortedSet<int>
? Could they ever be equal? They can have the same values - but the ordering of one is undefined.
Overall, the ideas of Object.Equals
and Object.GetHashCode
are too broad in my view. Often you want a particular type of equality - and often it makes no sense to compare objects for equality in the first place. This could easily form the subject of a completely different rant, but in the meantime I'm at least glad that .NET didn't try to apply this overly-broad idea to collections. The ability to use SetEquals
with a well-defined meaning is more useful, IMO.