All types in .NET support the Object.Equals()
method which, by default, compares two types for reference equality. However, sometimes, it also desirable to be able to compare two types for structural equality.
The best example of this is arrays, which with .NET 4 now implement the IStructuralEquatable
interface. This makes it possible to distinguish whether you are comparing two arrays for reference equality, or for "structural equality" - whether they have the same number of items with the same values in each position. Here's an example:
int[] array1 = new int[] { 1, 5, 9 };
int[] array2 = new int[] { 1, 5, 9 };
// using reference comparison...
Console.WriteLine( array1.Equals( array2 ) ); // outputs false
// now using structural comparison...
IStructuralEquatable eqArray1 = array1;
Console.WriteLine( eqArray1.Equals( array2 ) ); // outputs true
Other types which implement structural equality/comparability include tuples and anonymous types - which both clearly benefit from the ability to perform comparison based on their structure and content.
A question you didn't ask is:
Why do we have IStructuralComparable
and IStructuralEquatable
when there already
exist the IComparable
and IEquatable
interfaces?
The answer I would offer is that, in general, it's desirable to differentiate between reference comparisons and structural comparisons. It's normally expected that if you implement IEquatable<T>.Equals
you will also override Object.Equals
to be consistent. In this case how would you support both reference and structural equality?