using System.Collections.Generic;
using System.Linq;
namespace YourProject.Extensions
{
public static class ListExtensions
{
public static bool SetwiseEquivalentTo<T>(this List<T> list, List<T> other)
where T: IEquatable<T>
{
if (list.Except(other).Any())
return false;
if (other.Except(list).Any())
return false;
return true;
}
}
}
บางครั้งคุณจำเป็นต้องรู้ว่าสองรายการนั้นแตกต่างกันหรือไม่และไม่ใช่ความแตกต่างนั้น ๆ ในกรณีดังกล่าวให้ลองเพิ่มวิธีส่วนขยายนี้ในโครงการของคุณ โปรดทราบว่าวัตถุจดทะเบียนของคุณควรใช้ IEquatable!
การใช้งาน:
public sealed class Car : IEquatable<Car>
{
public Price Price { get; }
public List<Component> Components { get; }
...
public override bool Equals(object obj)
=> obj is Car other && Equals(other);
public bool Equals(Car other)
=> Price == other.Price
&& Components.SetwiseEquivalentTo(other.Components);
public override int GetHashCode()
=> Components.Aggregate(
Price.GetHashCode(),
(code, next) => code ^ next.GetHashCode()); // Bitwise XOR
}
ไม่ว่าComponent
ชั้นเรียนจะเป็นแบบใดวิธีการที่แสดงไว้ที่นี่Car
ควรนำไปใช้งานเกือบจะเหมือนกันทุกประการ
มันสำคัญมากที่จะต้องทราบว่าเราเขียน GetHashCode อย่างไร เพื่อให้ถูกต้องใช้IEquatable
, Equals
และGetHashCode
ต้องดำเนินการเกี่ยวกับคุณสมบัติของอินสแตนซ์ในทางที่เข้ากันได้อย่างมีเหตุผล
สองรายการที่มีเนื้อหาเดียวกันยังคงเป็นวัตถุที่แตกต่างกันและจะสร้างรหัสแฮชที่แตกต่างกัน เนื่องจากเราต้องการให้ทั้งสองรายการได้รับการปฏิบัติเท่าเทียมกันเราจะต้องให้GetHashCode
คุณค่าที่เหมือนกันสำหรับแต่ละรายการ เราสามารถทำสิ่งนี้ได้โดยมอบหมาย hashcode ให้กับทุกองค์ประกอบในรายการและใช้ bitor มาตรฐาน XOR เพื่อรวมทั้งหมด XOR เป็นผู้ไม่เชื่อเรื่องคำสั่งดังนั้นจึงไม่สำคัญว่ารายการจะถูกจัดเรียงแตกต่างกันหรือไม่ มันสำคัญแค่ว่าพวกเขาไม่มีอะไรนอกจากสมาชิกที่เทียบเท่า
หมายเหตุ: ชื่อแปลก ๆ ก็คือการบอกเป็นนัยถึงความจริงที่ว่าวิธีการไม่พิจารณาลำดับขององค์ประกอบในรายการ หากคุณสนใจลำดับขององค์ประกอบในรายการวิธีนี้ไม่เหมาะสำหรับคุณ!