The
IStructuralEquatable
interface in C# defines methods to support the comparison of objects for
structural equality
. This means two objects are considered equal if they have the same structure and equal values, rather than being the same reference.
This interface is particularly useful for collections like arrays, tuples, and other composite objects where you want to compare the actual content rather than object references.
Syntax
The interface defines two methods −
public interface IStructuralEquatable {
bool Equals(object other, IEqualityComparer comparer);
int GetHashCode(IEqualityComparer comparer);
Methods
Equals(Object, IEqualityComparer)
Determines whether an object is structurally equal to the current instance using the specified comparer.
GetHashCode(IEqualityComparer)
Returns a hash code for the current instance using the specified comparer.
Using IStructuralEquatable with Tuples
Tuples implement
IStructuralEquatable
, allowing you to compare their contents structurally −
Example
using System;
using System.Collections;
class Program {
public static void Main() {
var tupleOne = Tuple.Create(26.3, Double.NaN, 35.6);
var tupleTwo = Tuple.Create(26.3, Double.NaN, 35.6);
Console.WriteLine("Reference equality: " + object.ReferenceEquals(tupleOne, tupleTwo));
Console.WriteLine("Default equality: " + tupleOne.Equals(tupleTwo));
IStructuralEquatable structuralTuple = tupleOne;
Console.WriteLine("Structural equality: " +
structuralTuple.Equals(tupleTwo, EqualityComparer<object>.Default));
The output of the above code is −
Reference equality: False
Default equality: True
Structural equality: True
Using IStructuralEquatable with Arrays
Arrays also implement
IStructuralEquatable
for element-wise comparison −
Example
using System;
using System.Collections;
class Program {
public static void Main() {
int[] array1 = { 1, 2, 3 };
int[] array2 = { 1, 2, 3 };
int[] array3 = { 1, 2, 4 };
Console.WriteLine("Default array equality: " + array1.Equals(array2));
IStructuralEquatable structArray1 = array1;
Console.WriteLine("Structural equality (same values): " +
structArray1.Equals(array2, EqualityComparer<object>.Default));
Console.WriteLine("Structural equality (different values): " +
structArray1.Equals(array3, EqualityComparer<object>.Default));
The output of the above code is −
Default array equality: False
Structural equality (same values): True
Structural equality (different values): False
Custom IEqualityComparer
You can provide custom comparison logic by implementing
IEqualityComparer
−
Example
using System;
using System.Collections;
class CaseInsensitiveComparer : IEqualityComparer {
public new bool Equals(object x, object y) {
if (x is string && y is string) {
return string.Equals((string)x, (string)y, StringComparison.OrdinalIgnoreCase);
return object.Equals(x, y);
public int GetHashCode(object obj) {
return obj is string ? ((string)obj).ToLower().GetHashCode() : obj.GetHashCode();
class Program {
public static void Main() {
var tuple1 = Tuple.Create("Hello", "World");
var tuple2 = Tuple.Create("HELLO", "WORLD");
IStructuralEquatable structTuple = tuple1;
Console.WriteLine("Default comparer: " +
structTuple.Equals(tuple2, EqualityComparer<object>.Default));
Console.WriteLine("Case-insensitive comparer: " +
structTuple.Equals(tuple2, new CaseInsensitiveComparer()));
The output of the above code is −
Default comparer: False
Case-insensitive comparer: True
Conclusion
The
IStructuralEquatable
interface enables deep comparison of composite objects like arrays and tuples based on their content rather than reference. It provides flexibility through custom
IEqualityComparer
implementations, making it essential for value-based equality scenarios in collections and data structures.
Tutorials Point is a leading Ed Tech company striving to provide the best learning material on technical and non-technical subjects.