简体   繁体   English

C# Net.Core Object.Equals() 返回 false 即使两个对象相同

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

I am trying to return a list of recommended movies based on a client's favorite movies genres without including those that are already his favorites.我正在尝试根据客户最喜欢的电影类型返回推荐电影列表,而不包括那些已经是他最喜欢的电影。

So, here is my Movie object所以,这是我的电影 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);
        }
    }
}

And here is my Client object这是我的客户 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;
    }

Here's my movie list这是我的电影清单

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

And my client would be like this我的客户会是这样的

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

That mean that client2 favorite movies titles Cannery Row (which is movie2 ) and Delitto in Formula Uno (which is movie7 ).这意味着client2最喜欢的电影标题 Cannery Row (即movie2 )和 Formula Uno 中的 Delitto (即movie7 )。 Favorite genres list would be最喜欢的流派列表是

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

And the function that will return the movie recommendations is将返回电影推荐的 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;
    }

In theory, movie recommendations based on client's favorite movies genres list without including those that he already likes should be理论上,基于客户最喜欢的电影类型列表而不包括他已经喜欢的电影推荐应该是

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

But the assertion is failing because the return list is also including "Cannery Row" and "Delitto in Formula Uno"但断言失败了,因为返回列表还包括"Cannery Row""Delitto in Formula Uno"

I also tried in this way with the same results:我也以这种方式尝试了相同的结果:

            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;

I've also tried comparing Movie Title properties or GetHashCode() function without any success.我还尝试比较电影Title属性或GetHashCode() function 没有任何成功。

When I am debugging the test, I can see that Equals(movie) returns the result that I am expecting, so I am thinking I am doing something wrong at the LINQ query.当我调试测试时,我可以看到Equals(movie)返回了我期望的结果,所以我认为我在 LINQ 查询中做错了。

Any help would be really appreciated任何帮助将非常感激

First you could to exclude movies you alread have in the client list and then filter by genres combination首先,您可以排除客户列表中已有的电影,然后按流派组合过滤

It works:有用:

   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