การนำ IEquatable ไปใช้
จัดเตรียมการตรวจสอบความเท่ากันที่ปลอดภัยต่อชนิดข้อมูลด้วย Equals
การนำ IEquatable ไปใช้ เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงใช้ IEquatable<T>?
IEquatable<T> จัดเตรียมเมธอด Equals(T other) ที่มีชนิดข้อมูลชัดเจน ช่วยหลีกเลี่ยงการบรรจุค่าสำหรับชนิดข้อมูลค่าและหลีกเลี่ยงการแปลงชนิดสำหรับชนิดข้อมูลอ้างอิง ทำให้การตรวจสอบความเท่ากันทั้งเร็วขึ้นและชัดเจนขึ้น
การนำอินเทอร์เฟซไปใช้
นำ IEquatable<T> ไปใช้และจัดเตรียม Equals(T other) นอกจากนี้ควรโอเวอร์ไรด์ object.Equals และ GetHashCode ที่สืบทอดมา เพื่อให้เส้นทางทั้งหมดสอดคล้องกัน
using System;
public struct Point : IEquatable<Point>
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public bool Equals(Point other) => X == other.X && Y == other.Y;
public override bool Equals(object obj) => obj is Point p && Equals(p);
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Point(1, 2).Equals(new Point(1, 2)));
}
}หลีกเลี่ยงการบรรจุค่าสำหรับโครงสร้าง
object.Equals(object) ที่ไม่ใช้ชนิดข้อมูลทั่วไปจะบรรจุอาร์กิวเมนต์ที่เป็นโครงสร้าง ส่วน Equals(Point other) ที่มีชนิดข้อมูลจาก IEquatable<T> จะรับโครงสร้างโดยตรง จึงไม่เกิดการจองหน่วยความจำ
using System;
public struct Point : IEquatable<Point>
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public bool Equals(Point other) => X == other.X && Y == other.Y; // no boxing
public override bool Equals(object obj) => obj is Point p && Equals(p);
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
Point a = new Point(3, 4);
Point b = new Point(3, 4);
Console.WriteLine(a.Equals(b)); // calls the typed overload
}
}คอลเลกชันใช้ IEquatable<T>
List<T>.Contains, Dictionary และ HashSet จะเลือกใช้ IEquatable<T>.Equals หากมี การนำสิ่งนี้ไปใช้ทำให้การดำเนินการเหล่านี้มีประสิทธิภาพและถูกต้องสำหรับชนิดข้อมูลของคุณ
using System;
using System.Collections.Generic;
public struct Point : IEquatable<Point>
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public bool Equals(Point other) => X == other.X && Y == other.Y;
public override bool Equals(object obj) => obj is Point p && Equals(p);
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
var list = new List<Point> { new Point(0, 0), new Point(1, 1) };
Console.WriteLine(list.Contains(new Point(1, 1)));
}
}ชนิดข้อมูลอ้างอิงกับ IEquatable<T>
คลาสก็สามารถนำ IEquatable<T> ไปใช้ได้เช่นกัน เมธอด Equals ที่มีชนิดข้อมูลชัดเจนช่วยหลีกเลี่ยงการแปลงชนิด และคุณต้องจัดการกับ null อย่างชัดเจนสำหรับพารามิเตอร์อ้างอิง
using System;
public class Person : IEquatable<Person>
{
public string Name;
public Person(string name) { Name = name; }
public bool Equals(Person other) => other != null && other.Name == Name;
public override bool Equals(object obj) => Equals(obj as Person);
public override int GetHashCode() => Name?.GetHashCode() ?? 0;
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Person("Ada").Equals(new Person("Ada")));
Console.WriteLine(new Person("Ada").Equals((Person)null));
}
}ให้ object.Equals เรียกใช้เมธอดที่มีชนิดข้อมูลชัดเจน
รูปแบบที่สะอาดคือเขียนการเปรียบเทียบไว้เพียงครั้งเดียวใน Equals(T) แล้วให้ object.Equals ส่งต่อการทำงานไปยังเมธอดนั้น วิธีนี้รับประกันว่าทั้งสองเมธอดจะทำงานเหมือนกันทุกประการ
using System;
public struct Id : IEquatable<Id>
{
public int Value;
public Id(int value) { Value = value; }
public bool Equals(Id other) => Value == other.Value;
public override bool Equals(object obj) => obj is Id other && Equals(other);
public override int GetHashCode() => Value;
}
public class Program
{
public static void Main()
{
object boxed = new Id(5);
Console.WriteLine(boxed.Equals(new Id(5)));
}
}การเปรียบเทียบหลายฟิลด์
สำหรับชนิดข้อมูลที่มีหลายฟิลด์ ให้เปรียบเทียบฟิลด์ทั้งหมดใน Equals อินสแตนซ์สองรายการจะเท่ากันก็ต่อเมื่อฟิลด์ที่เกี่ยวข้องทุกฟิลด์มีค่าตรงกัน
using System;
public struct DateRange : IEquatable<DateRange>
{
public int Start, End;
public DateRange(int start, int end) { Start = start; End = end; }
public bool Equals(DateRange other) => Start == other.Start && End == other.End;
public override bool Equals(object obj) => obj is DateRange d && Equals(d);
public override int GetHashCode() => HashCode.Combine(Start, End);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new DateRange(1, 5).Equals(new DateRange(1, 5)));
Console.WriteLine(new DateRange(1, 5).Equals(new DateRange(1, 6)));
}
}จับคู่กับตัวดำเนินการ
ใช้ IEquatable<T> ร่วมกับ == และ != เพื่อให้ผู้ใช้เปรียบเทียบได้ด้วยไวยากรณ์ทั้งสองแบบ โดยมีการเปรียบเทียบที่มีชนิดข้อมูลชัดเจนแบบเดียวกันอยู่เบื้องหลัง
using System;
public struct Money : IEquatable<Money>
{
public decimal Amount;
public Money(decimal a) { Amount = a; }
public bool Equals(Money other) => Amount == other.Amount;
public override bool Equals(object obj) => obj is Money m && Equals(m);
public override int GetHashCode() => Amount.GetHashCode();
public static bool operator ==(Money a, Money b) => a.Equals(b);
public static bool operator !=(Money a, Money b) => !a.Equals(b);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Money(9.99m) == new Money(9.99m));
}
}ระเบียนนำสิ่งนี้ไปใช้โดยอัตโนมัติ
record ของ C# จะสร้าง IEquatable<T>, Equals ที่อิงค่า และ GetHashCode ให้โดยอัตโนมัติ เมื่อคุณต้องการเพียงการตรวจสอบความเท่ากันโดยอิงค่า ระเบียนจะช่วยลดโค้ดส่วนเกินได้
using System;
public record Point(int X, int Y);
public class Program
{
public static void Main()
{
var a = new Point(1, 2);
var b = new Point(1, 2);
Console.WriteLine(a.Equals(b));
Console.WriteLine(a == b);
}
}เมื่อใดควรนำไปใช้ด้วยตนเอง
นำ IEquatable<T> ไปใช้ด้วยตนเองเมื่อคุณต้องการกฎการตรวจสอบความเท่ากันแบบกำหนดเอง เช่น ชื่อที่ไม่คำนึงถึงตัวพิมพ์เล็กใหญ่ หรือการละเว้นบางฟิลด์ ซึ่งระเบียนไม่สามารถแสดงได้โดยตรง
using System;
public class CaseInsensitiveTag : IEquatable<CaseInsensitiveTag>
{
public string Name;
public CaseInsensitiveTag(string name) { Name = name; }
public bool Equals(CaseInsensitiveTag other)
=> other != null && string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase);
public override bool Equals(object obj) => Equals(obj as CaseInsensitiveTag);
public override int GetHashCode() => Name?.ToLowerInvariant().GetHashCode() ?? 0;
}
public class Program
{
public static void Main()
{
Console.WriteLine(new CaseInsensitiveTag("Red").Equals(new CaseInsensitiveTag("RED")));
}
}ลองทำด้วยตนเอง
นำ IEquatable<T> ไปใช้กับชนิดข้อมูลอ้างอิงขนาดเล็ก และให้ทุกเส้นทางการตรวจสอบความเท่ากันเรียกผ่านเมธอดที่มีชนิดข้อมูลชัดเจน
using System;
using System.Collections.Generic;
public class Coordinate : IEquatable<Coordinate>
{
public int Lat, Lng;
public Coordinate(int lat, int lng) { Lat = lat; Lng = lng; }
public bool Equals(Coordinate other) => other != null && other.Lat == Lat && other.Lng == Lng;
public override bool Equals(object obj) => Equals(obj as Coordinate);
public override int GetHashCode() => HashCode.Combine(Lat, Lng);
}
public class Program
{
public static void Main()
{
var set = new HashSet<Coordinate> { new Coordinate(10, 20) };
Console.WriteLine(set.Contains(new Coordinate(10, 20)));
}
}ตรวจสอบอย่างรวดเร็ว
ทบทวนประโยชน์ของ IEquatable
สรุปทบทวน
IEquatable<T> มอบการตรวจสอบความเท่ากันที่ปลอดภัยด้านชนิดข้อมูล
- จัดเตรียม
Equals(T other)ซึ่งช่วยหลีกเลี่ยงการบรรจุค่าสำหรับโครงสร้างและการแปลงชนิดสำหรับคลาส - คอลเลกชันจะเลือกใช้สิ่งนี้เพื่อการค้นหาที่ถูกต้องและมีประสิทธิภาพ
- ให้
object.Equalsและตัวดำเนินการเรียกผ่านเมธอดที่มีชนิดข้อมูลชัดเจน - ระเบียนนำสิ่งนี้ไปใช้โดยอัตโนมัติ ส่วนกฎแบบกำหนดเองควรนำไปใช้ด้วยตนเอง
คำถามที่พบบ่อย
บทเรียน “การนำ IEquatable ไปใช้” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การนำ IEquatable ไปใช้” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การนำ IEquatable ไปใช้”
จัดเตรียมการตรวจสอบความเท่ากันที่ปลอดภัยต่อชนิดข้อมูลด้วย Equals คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “การนำ IEquatable ไปใช้” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การนำ IEquatable ไปใช้
- การเขียนทับ GetHashCode
- การนำ IComparable ไปใช้
- IComparer สำหรับการเรียงลำดับแบบกำหนดเอง