Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
What does the interface IStructuralEquatable do in C#?
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
| Method | Description |
|---|---|
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.
