簡體   English   中英

C# Net.Core Object.Equals() 返回 false 即使兩個對象相同

[英]C# Net.Core Object.Equals() returning false even if both objects are the same

我正在嘗試根據客戶最喜歡的電影類型返回推薦電影列表,而不包括那些已經是他最喜歡的電影。

所以,這是我的電影 object

 public class Movie
{
    /// <summary>
    /// Movie's title
    /// </summary>
    public string Title { get; set; }
    
    /// <summary>
    /// Movie's gengres list
    /// </summary>
    public List<string> Genres { get; set; }

    private int HashCode 
    {
        get
        {
            return this.Title.GetHashCode();
        }
    }

    /// <summary>
    /// Public default constructor. Initializes an empty Movie object
    /// </summary>
    public Movie()
    {
        Genres = new List<string>();
    }

    /// <summary>
    /// Initializes a Movie object with a given title
    /// </summary>
    /// <param name="title">Movie title</param>
    public Movie(string title)
    {
        Title = title;
        Genres = new List<string>();
    }

    /// <summary>
    /// Override ToString function
    /// </summary>
    /// <returns>Movie's title</returns>
    public override string ToString()
    {
        return Title;
    }

    public override int GetHashCode()
    {
        return HashCode;
    }

    public override bool Equals(object obj)
    {
        if ((obj == null) || !this.GetType().Equals(obj.GetType()))
        {
            return false;
        }
        else
        {
            Movie movie = (Movie)obj;
            return (HashCode == movie.HashCode);
        }
    }
}

這是我的客戶 object

public class Client
{
    /// <summary>
    /// Client's First Name
    /// </summary>
    public string FirstName { get; set; }

    /// <summary>
    /// Client's Last Name
    /// </summary>
    public string LastName { get; set; }

    /// <summary>
    /// Client's full name
    /// </summary>
    public string FullName 
    {
        get
        {
            return $"{FirstName} {LastName}";
        }
    }

    /// <summary>
    /// Client's favorite movies
    /// </summary>
    public List<Movie> FavoriteMovies { get; set; }

    /// <summary>
    /// Public default constructor. Initializes an empty client
    /// </summary>
    public Client()
    {
        FavoriteMovies = new List<Movie>();
    }

    /// <summary>
    /// Initializes a client object with a given name
    /// </summary>
    /// <param name="firstName">Client's first name</param>
    /// <param name="lastName">Client's last name</param>
    public Client(string firstName, string lastName)
    {
        FirstName = firstName;
        FavoriteMovies = new List<Movie>();
    }

    /// <summary>
    /// Initializes a client object with given name and list of favorite movies
    /// </summary>
    /// <param name="firstName">Client's first name</param>
    /// <param name="lastName">Client's last name</param>
    /// <param name="favoriteMovies">Client's list of favorite movies</param>
    public Client(string firstName, string lastName, List<Movie> favoriteMovies)
    {
        FirstName = firstName;
        LastName = lastName;
        FavoriteMovies = favoriteMovies;
    }

    /// <summary>
    /// Override ToString function that will return Client's full name
    /// </summary>
    /// <returns>Client's full name</returns>
    public override string ToString()
    {
        return FullName;
    }

這是我的電影清單

        Movies = new List<Movie>();

        Movie movie1 = new Movie("Untitled Screenplay, adapted from the book, the Price of Fame, the biography of Dennis Price. Written by Eliane Parker and Gareth Owen.");
        movie1.Genres.Add("Action");
        Movies.Add(movie1);

        Movie movie2 = new Movie("Cannery Row");
        movie2.Genres.Add("Comedy");
        movie2.Genres.Add("Drama");
        movie2.Genres.Add("Romance");
        Movies.Add(movie2);

        Movie movie3 = new Movie("Body Melt");
        movie3.Genres.Add("Comedy");
        movie3.Genres.Add("Horror");
        movie3.Genres.Add("Sci-Fi");
        Movies.Add(movie3);

        Movie movie4 = new Movie("Ghost Lab");
        movie4.Genres.Add("Drama");
        movie4.Genres.Add("Horror");
        movie4.Genres.Add("Thriller");
        Movies.Add(movie4);

        Movie movie5 = new Movie("Biography: WWE Legends Biography: Booker T");
        movie5.Genres.Add("Action");
        Movies.Add(movie5);

        Movie movie6 = new Movie("Zombie Wars");
        movie6.Genres.Add("Action");
        Movies.Add(movie6);

        Movie movie7 = new Movie("Delitto in Formula Uno");
        movie7.Genres.Add("Comedy");
        movie7.Genres.Add("Crime");
        movie7.Genres.Add("Thriller");
        Movies.Add(movie7);

        Movie movie8 = new Movie("The Long and Winding Road");
        movie8.Genres.Add("Comedy");
        movie8.Genres.Add("Drama");
        Movies.Add(movie8);

我的客戶會是這樣的

        Client client2 = new Client("Belinda", "Reed");
        client2.FavoriteMovies.Add(movie2);
        client2.FavoriteMovies.Add(movie7);
        Clients.Add(client2);

這意味着client2最喜歡的電影標題 Cannery Row (即movie2 )和 Formula Uno 中的 Delitto (即movie7 )。 最喜歡的流派列表是

"Comedy"
"Drama"
"Romance"
"Crime"
"Thriller"

將返回電影推薦的 function 是

    public static List<Movie> MovieRecommendationsByClient(Client client, List<Movie> moviesCatalog)
    {
        var recommendations = moviesCatalog
            .Where(movie => client.FavoriteMovies
                                    .Any(cm => (!cm.Equals(movie)
                                        && cm.Genres.Intersect(movie.Genres).Any()))).ToList();


        return recommendations;
    }

理論上,基於客戶最喜歡的電影類型列表而不包括他已經喜歡的電影推薦應該是

"Body Melt"
"Ghost Lab"
"The Long and Winding Road"

但斷言失敗了,因為返回列表還包括"Cannery Row""Delitto in Formula Uno"

我也以這種方式嘗試了相同的結果:

            var recommendations = from movie in moviesCatalog
                              from clientMovie in client.FavoriteMovies
                              where !clientMovie.Equals(movie) && movie.Genres.Intersect(clientMovie.Genres).Any()
                              group movie by movie into moviesGroup
                              select moviesGroup.Key;

我還嘗試比較電影Title屬性或GetHashCode() function 沒有任何成功。

當我調試測試時,我可以看到Equals(movie)返回了我期望的結果,所以我認為我在 LINQ 查詢中做錯了。

任何幫助將非常感激

首先,您可以排除客戶列表中已有的電影,然后按流派組合過濾

有用:

   var recommendations = moviesCatalog.Except(client.FavoriteMovies)
            .Where(movie => client.FavoriteMovies
            .Any(cm => cm.Genres.Intersect(movie.Genres).Any())).ToList();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM