LINQ の Distinct()
とカスタム オブジェクト: よくある落とし穴
LINQ の Distinct()
メソッドを使用すると、コレクションからの重複の削除が簡単になります。 ただし、カスタム オブジェクトでは予期しない動作が発生し、プロパティに基づいて重複を識別できないことがよくあります。
問題: 参照と値の同等性
問題は、Distinct()
がオブジェクトを比較する方法にあります。これは参照の等価性を使用します。つまり、2 つのオブジェクトが同じメモリ位置を占有しない限り、別個のものとみなされます。 これは、2 つのカスタム オブジェクトが同じプロパティ値を持っている場合でも、Distinct()
はそれらを別個のエンティティとして扱います。
説明例: 重複した著者
それぞれの本のリストに著者のリストが含まれていると想像してください。 2 つの書籍に同じ著者 (姓名が同じ) がリストされている場合でも、Distinct()
は別個のオブジェクト インスタンスであるため、重複する著者エントリは削除されません。
解決策: IEquatable<T>
これを解決するには、カスタム オブジェクト クラスに IEquatable<T>
インターフェイス (例: Author
) を実装します。このインターフェイスは Equals()
メソッドと GetHashCode()
メソッドを必須にし、オブジェクトの同等性を決定する方法を定義できるようにします。 これらのメソッドをオーバーライドすることで、参照ではなくプロパティ値に基づいて比較するように Distinct()
に指示できます。
強化された Author
クラス
これは、Author
を実装する改良された IEquatable<Author>
クラスです。
<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 (other == null) return false; return FirstName == other.FirstName && LastName == other.LastName; } public override int GetHashCode() { return (FirstName?.GetHashCode() ?? 0) ^ (LastName?.GetHashCode() ?? 0); } }</code>
解決策: 値ベースの比較
IEquatable<Author>
を実装することにより、Equals()
メソッドは FirstName
と LastName
に基づいて著者を比較するようになりました。 GetHashCode()
メソッドは、同じ値を持つオブジェクトの一貫したハッシュを保証します。 Distinct()
は、名前に基づいて重複した作成者を正しく識別し、削除するようになりました。
結論: Distinct()
IEquatable<T>
を実装すると、カスタム オブジェクトが等しいかどうかを比較する方法を制御する重要なメカニズムが提供され、値ベースの重複を処理するときに Distinct()
が正しく機能できるようになります。 これにより、Distinct()
が意図したとおりに動作し、重要であると定義したプロパティに基づいて重複が削除されます。
以上がLINQ の Distinct がカスタム オブジェクトで機能しないのはなぜですか?それを修正するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。