Distinct が LINQ to Objects で動作しない [重複] 質問する

Distinct が LINQ to Objects で動作しない [重複] 質問する
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"
                    },                       
                }
            },
            new Book
            {
                Name="LINQ in Action",
                Authors = new List<Author>
                {
                    new Author 
                    {
                        FirstName = "Fabrice", LastName="Marguerie"
                    },
                     new Author 
                    {
                        FirstName = "Steve", LastName="Eichert"
                    },
                     new Author 
                    {
                        FirstName = "Jim", LastName="Wooley"
                    },
                }
            },
        };


        var temp = books.SelectMany(book => book.Authors).Distinct();
        foreach (var author in temp)
        {
            Console.WriteLine(author.FirstName + " " + author.LastName);
        }

        Console.Read();
    }

}
public class Book
{
    public string Name { get; set; }
    public List<Author> Authors { get; set; }
}
public class Author
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public override bool Equals(object obj)
    {
        return true;
        //if (obj.GetType() != typeof(Author)) return false;
        //else return ((Author)obj).FirstName == this.FirstName && ((Author)obj).FirstName == this.LastName;
    }

}

これは、「LINQ in Action」の例に基づいています。リスト 4.16。

これは Jon Skeet を 2 回出力します。なぜでしょうか? Author クラスの Equals メソッドをオーバーライドしようとしました。それでも Distinct は機能しないようです。何が足りないのでしょうか?

編集: == および != 演算子のオーバーロードも追加しました。それでもまだ役に立ちません。

 public static bool operator ==(Author a, Author b)
    {
        return true;
    }
    public static bool operator !=(Author a, Author b)
    {
        return false;
    }

ベストアンサー1

LINQ Distinct は、カスタム オブジェクトに関してはそれほどスマートではありません。

リストを調べて、2 つの異なるオブジェクトがあることを確認するだけです (メンバー フィールドに同じ値があるかどうかは関係ありません)。

回避策の1つは、IEquatableインターフェースを次のように実装することです。ここ

Author クラスを次のように変更すると動作するはずです。

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;
    }

    public override int GetHashCode()
    {
        int hashFirstName = FirstName == null ? 0 : FirstName.GetHashCode();
        int hashLastName = LastName == null ? 0 : LastName.GetHashCode();

        return hashFirstName ^ hashLastName;
    }
}

DotNetFiddleとして試してみる

おすすめ記事