使用IEquatable處理LINQ Distinct中的物件相等性
LINQ的Distinct
方法旨在根據物件的相等性識別唯一物件。但是,對於自訂對象,它可能並不總是按預期工作。
在提供的範例中,Distinct
方法未能辨識名稱相同的兩個Author
物件為重複項。這是因為LINQ根據物件的引用位址而不是其屬性值將物件視為不同的。
為了解決這個問題,可以在Author
類別中實作IEquatable
介面。透過重寫Equals
方法,您可以定義自訂邏輯,以根據屬性值FirstName
和LastName
確定相等性。下面的實作檢查兩個欄位中的匹配值以確定相等性:
public class Author : IEquatable<Author> { public string FirstName { get; set; } public string LastName { get; set; } public bool Equals(Author other) { if (FirstName == other?.FirstName && LastName == other?.LastName) return true; return false; } // 为保持一致性而重写GetHashCode public override int GetHashCode() { return (FirstName?.GetHashCode() ?? 0) ^ (LastName?.GetHashCode() ?? 0); } }
用法:
應用此自訂實作解決了Distinct
的問題。修改後的程式碼正確地識別了重複的Author
對象,並從結果中刪除了其中一個:
using System.Collections.Generic; using System.Linq; class Program { static void Main(string[] args) { // 使用重复作者初始化书籍列表 List<Book> books = new List<Book> { new Book { Name = "C# in Depth", Authors = new List<Author> { new Author { FirstName = "Jon", LastName = "Skeet" }, new Author { FirstName = "Jon", LastName = "Skeet" }, } }, // ... }; // 选择作者,应用Distinct,并打印 var temp = books.SelectMany(book => book.Authors).Distinct(); foreach (var author in temp) { Console.WriteLine($"{author.FirstName} {author.LastName}"); } Console.Read(); } }
結論:
實作IEquatable
並重寫Equals
方法允許在LINQ操作中自訂物件相等性的定義。這確保了Distinct
方法根據其屬性而不是引用地址正確處理自訂物件。
請注意,程式碼範例中已對GetHashCode
方法進行了改進,以確保與Equals
方法的一致性,並使用了null-conditional operator (?.) 來處理可能為null的屬性。 這避免了潛在的NullReferenceException
異常。
以上是如何確保 LINQ 的 Distinct 方法與自訂物件正確的物件相等?的詳細內容。更多資訊請關注PHP中文網其他相關文章!