Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

Interface IStructuralEquatable ใน C#

Interface IStructuralEquatable ใน C#

IStructuralEquatable ใช้สำหรับเปรียบเทียบความเท่าเทียมแบบโครงสร้าง (Structural Equality) คือ เปรียบเทียบค่าของแต่ละ Element แทน Reference Equality ใช้กับ Tuple และ Array

เมธอดหลัก 2 ตัว

เมธอดคำอธิบาย
Equals(object other, IEqualityComparer comparer)ตรวจสอบว่า Structural Equal หรือไม่
GetHashCode(IEqualityComparer comparer)คำนวณ Hash Code แบบ Structural

ตัวอย่างกับ Tuple


using System;
using System.Collections;

class Program
{
    static void Main()
    {
        var tuple1 = Tuple.Create(26.3, double.NaN, 35.6);
        var tuple2 = Tuple.Create(26.3, double.NaN, 35.6);
        
        // Default Equality (Reference/Value) -> NaN != NaN ปกติ
        Console.WriteLine($"tuple1.Equals(tuple2): {tuple1.Equals(tuple2)}"); // False
        
        // Structural Equality ผ่าน IStructuralEquatable
        IStructuralEquatable structural = tuple1;
        bool equal = structural.Equals(tuple2, EqualityComparer.Default);
        Console.WriteLine($"Structural Equals: {equal}"); // True (NaN ถือว่าเท่ากันใน Structural)
        
        // HashCode
        int hash = structural.GetHashCode(EqualityComparer.Default);
        Console.WriteLine($"Structural HashCode: {hash}");
    }
}


ผลลัพธ์


tuple1.Equals(tuple2): False
Structural Equals: True
Structural HashCode: 12345678 (ตัวอย่าง)

เมื่อไหร่ควรใช้

  • เปรียบเทียบ Tuple หรือ Array โดยดูค่าภายใน (Deep Comparison)
  • ใช้เป็น Key ใน Dictionary/HashSet ที่ต้องการ Structural Equality
  • Implement เองใน Custom Class ได้ (Implement IStructuralEquatable)

โครงสร้างที่ Implement อยู่แล้ว

  • Array (ทุกประเภท)
  • Tuple Classes (Tuple<T1>, Tuple<T1,T2>, ...)
  • ValueTuple (C# 7.0+) - ใช้ Equality แบบ Structural โดย Default

ตัวอย่าง Custom Implementation


public class Point : IStructuralEquatable
{
    public int X, Y;
    
    public bool Equals(object other, IEqualityComparer comparer)
    {
        if (other is Point p)
            return comparer.Equals(X, p.X) && comparer.Equals(Y, p.Y);
        return false;
    }
    
    public int GetHashCode(IEqualityComparer comparer)
    {
        return comparer.GetHashCode(X) * 31 + comparer.GetHashCode(Y);
    }
}