ホームページ > バックエンド開発 > C++ > LINQ Distinct() がカスタム オブジェクトで期待どおりに動作しないのはなぜですか?

LINQ Distinct() がカスタム オブジェクトで期待どおりに動作しないのはなぜですか?

Susan Sarandon
リリース: 2025-01-20 19:28:10
オリジナル
717 人が閲覧しました

Why Doesn't LINQ Distinct() Work as Expected with Custom Objects?

カスタム オブジェクトの LINQ Distinct() メソッドの異常な動作

LINQ to Objects を使用する場合、カスタム オブジェクトを操作するときに Distinct() メソッドが常に期待どおりの結果を生成するとは限りません。既定では、LINQ は一意性の比較で参照のみを考慮します。

提供されたコード例には、Book オブジェクトのリストがあり、各オブジェクトには Author オブジェクトのリストが含まれています。 SelectMany() を使用して Authors コレクションを単一のリストにフラット化し、 Distinct() を呼び出すと、一意の作成者のみが返されることが期待されます。ただし、同じ著者 (Jon Skeet) が 2 回登場していることがわかります。

問題は、LINQ の Distinct() メソッドがデフォルトでオブジェクト参照を操作することです。リスト内には 2 つの別々の 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() とカスタム ラムダ式を使用して FirstNameLastName のタプルを定義することで、作成者の一意性を比較する方法を明示的に指定できます。

これらの手順に従うことで、Distinct() メソッドが重複する作成者を正確に識別し、その値を保持しながら削除することができます。

以上がLINQ Distinct() がカスタム オブジェクトで期待どおりに動作しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート