IEquatable を使用して、LINQ Distinct でオブジェクトの等価性を処理します
LINQ の Distinct
メソッドは、同等性に基づいて一意のオブジェクトを識別するように設計されています。ただし、カスタム オブジェクトの場合、常に期待どおりに動作するとは限りません。
この例では、Distinct
メソッドは同じ名前を持つ 2 つの Author
オブジェクトを重複として識別できませんでした。これは、LINQ がオブジェクトをプロパティ値ではなく参照アドレスに基づいて別のものとして扱うためです。
この問題を解決するために、Author
インターフェースを IEquatable
クラスに実装できます。 Equals
メソッドをオーバーライドすることで、プロパティ値 FirstName
と LastName
に基づいて等しいかどうかを判断するカスタム ロジックを定義できます。次の実装では、2 つのフィールドの一致する値をチェックして等しいかどうかを判断します。
<code class="language-csharp">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); } }</code>
使用法:
このカスタム実装を適用すると、 の問題が解決されます。変更されたコードは、重複した Distinct
オブジェクトを正しく識別し、結果からそれらの 1 つを削除します: Author
<code class="language-csharp">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(); } }</code>
結論:
を実装し、IEquatable
メソッドをオーバーライドすると、LINQ 操作でのオブジェクトの等価性の定義をカスタマイズできます。これにより、Equals
メソッドが参照アドレスではなくプロパティに基づいてカスタム オブジェクトを正しく処理できるようになります。 Distinct
メソッドとの一貫性を確保するために GetHashCode
メソッドが改良されており、null 条件演算子 (?.) を使用して null の可能性があるプロパティを処理していることに注意してください。 これにより、潜在的な Equals
例外が回避されます。 NullReferenceException
以上がカスタム オブジェクトを使用した LINQ の Distinct メソッドの正しいオブジェクトの同等性を確認するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。