LINQ Distinct() 方法在自訂物件中的異常行為
在使用 LINQ to Objects 時,Distinct()
方法在處理自訂物件時可能不會總是產生預期的結果。預設情況下,LINQ 只考慮引用進行唯一性比較。
在提供的程式碼範例中,您有一個 Book
物件列表,每個物件都包含一個 Author
物件列表。當您使用 SelectMany()
將 Authors
集合展平為單一列表,然後呼叫 Distinct()
時,您期望它只會傳回唯一的作者。但是,您觀察到同一個作者 (Jon Skeet) 出現了兩次。
問題在於,LINQ 中的 Distinct()
方法預設會基於物件參考進行操作。由於您的清單中存在兩個單獨的 Author
對象,即使它們具有相同的值,LINQ 也會認為它們是不同的。為了克服這個問題,您需要提供一個自訂的相等性實作來明確定義如何比較物件的唯一性。
重寫 Equals 方法
如您在問題中所建議的,您可以重寫 Author
類別中的 Equals()
方法來指定相等性條件。但是,您目前的實作總是回傳 true
,使得所有作者看起來都是相等的。
實作 IEquatable 介面
更合適的方法是在您的類別中實作 IEquatable<Author>
介面。此介面可讓您定義自訂相等性比較器。在您的情況下,您可以根據作者的姓名進行比較:
<code class="language-csharp">public class Author : IEquatable<Author> { public bool Equals(Author other) { return FirstName == other.FirstName && LastName == other.LastName; } }</code>
在 LINQ 查詢中重複使用作者
實作 IEquatable<Author>
後,您可以使用它來改善 Distinct()
方法的行為。修改您的 LINQ 查詢如下:
<code class="language-csharp">var temp = books.SelectMany(book => book.Authors).DistinctBy(a => new { a.FirstName, a.LastName });</code>
透過使用 DistinctBy()
和一個自訂 lambda 表達式來定義 FirstName
和 LastName
的元組,您可以明確指定如何比較作者的唯一性。
遵循這些步驟,您可以確保 Distinct()
方法正確識別並消除重複的作者,同時保留它們的值。
以上是為什麼 LINQ Distinct() 對於自訂物件不能如預期般運作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!