繁体   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