C# 如何正确地使用集合实现Equals
我有下面的类和MSDN记录的2个相等的方法C# 如何正确地使用集合实现Equals,c#,collections,equals,C#,Collections,Equals,我有下面的类和MSDN记录的2个相等的方法 public class Book { public string bookTitle {get; private set;} public IReadOnlyCollection<Author> authors {get; private set;} public string ISBN {get; private set;} public int numberofpages {get; private set; } public st
public class Book
{
public string bookTitle {get; private set;}
public IReadOnlyCollection<Author> authors {get; private set;}
public string ISBN {get; private set;}
public int numberofpages {get; private set; }
public string Genre {get; private set; }
public Book(string bookTitle, IReadOnlyCollection<Author> authors, string ISBN, int numberofpages, string genre)
{
if(string.IsNullOrWhiteSpace(bookTitle)){
throw new ArgumentNullException("Book Must Have Title!");
}
this.bookTitle = bookTitle;
if(authors.Count < 0){
throw new ArgumentNullException("You must provide at least one author!");
}
this.authors = new ReadOnlyCollection<Author>(new List<Author>(authors));
if(String.IsNullOrWhiteSpace(ISBN)){
throw new ArgumentNullException("A Book Has to have an ISBN number. Check online or the back cover");
}
this.ISBN = ISBN;
if(numberofpages <= 0){
throw new ArgumentNullException("A Book has more than one page!");
}
this.numberofpages = numberofpages;
if(String.IsNullOrWhiteSpace(genre)){
throw new ArgumentNullException("A Book has a genre. Find it and input it");
}
this.Genre = genre;
}
public override bool Equals(Object obj)
{
if (obj == null)
{
return false;
}
Book p = obj as Book;
if ((System.Object)p == null)
{
return false;
}
return (bookTitle == p.bookTitle) && (authors == p.authors) && (numberofpages == p.numberofpages) && (ISBN == p.ISBN) && (Genre == p.Genre);
}
public bool Equals(Book p)
{
if ((object)p == null)
{
return false;
}
return (bookTitle == p.bookTitle) && (authors == p.authors) && (numberofpages == p.numberofpages) && (ISBN == p.ISBN) && (Genre == p.Genre);
}
public class Author
{
public int ID {get; private set;}
public string firstname {get; private set;}
public string lastname {get; private set;}
public(int id, string firstname, string lastname)
{
this.ID = id;
this.firstname = firstname;
this.lastname = lastname;
}
//Rest of code here: just toString method
公共课堂教材
{
公共字符串bookTitle{get;private set;}
公共IReadOnlyCollection作者{get;private set;}
公共字符串ISBN{get;private set;}
public int numberofpages{get;private set;}
公共字符串类型{get;private set;}
公共图书(字符串书名、IReadOnlyCollection作者、字符串ISBN、整数页数、字符串类型)
{
if(string.IsNullOrWhiteSpace(bookTitle)){
抛出新的ArgumentNullException(“书必须有标题!”);
}
this.bookTitle=bookTitle;
如果(authors.Count<0){
抛出新ArgumentNullException(“您必须至少提供一个作者!”);
}
this.authors=新的只读集合(新列表(作者));
if(String.IsNullOrWhiteSpace(ISBN)){
抛出新的ArgumentNullException(“一本书必须有一个ISBN号,请在线或封底查阅”);
}
这是ISBN=ISBN;
如果(numberofpages您的图书类可以/应该实现和。您可能还希望对收藏进行排序。如果没有更多信息,很难推荐一个坚如磐石的答案,但如果您查看我提供的链接/建议,您的项目可能会取得很好的进展。您必须比较作者列表项。排序和比较是作者在每个索引上的位置,直到它们不相等或您到达列表的末尾。此外,Book和author都应该实现IEquatable以防止问题并保持理智。@MaxSorin-您能告诉我如何实现吗?答案随代码和接口一起提供实现。谢谢,但是,作者并没有这么复杂。它只是一个类使用int author ID、string authorFirstname、string authorLastName。Authors
只允许我在一条语句中相互比较列表。您可以创建自己的方法来比较ReadOnlyCollections
中的项目。我更新了我的代码以包含我的Authors类,如果您可以更改代码,请查看,以便我能理解该怎么做。向下滚动它与我在一起。我正在学习,你能告诉我如何创建我自己的方法来比较ReadOnlyCollections中的项目吗?为什么这还不足以让equals方法工作?
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestArea.Other
{
public class Author : IComparable<Author>
{
public string Name { get; set; }
public int CompareTo(Author other) => this.Name.CompareTo(other.Name);
}
public class Authors : ReadOnlyCollection<Author>, IEquatable<Authors>
{
public Authors(IList<Author> list) : base(list)
{
}
public bool Equals(Authors other)
{
//reference equal
if (other == this)
{
return true;
}
//No need to iterate over authors
if (other == null || other.Count != this.Count)
{
return false;
}
var thisSorted = this.ToArray();
var otherSorted = other.ToArray();
Array.Sort(thisSorted);
Array.Sort(otherSorted );
for (int i = 0; i < thisSorted.Length; i++)
{
if (thisSorted[i].CompareTo(otherSorted[i]) != 0)
{
return false;
}
}
return true;
}
}
public class Book : IEquatable<Book>
{
public string bookTitle { get; private set; }
public Authors authors { get; private set; }
public string ISBN { get; private set; }
public int numberofpages { get; private set; }
public string Genre { get; private set; }
//Made Authors parameter as simplified as it could be
public Book(string bookTitle, IEnumerable<Author> authors, string ISBN, int numberofpages, string genre)
{
var authorList = authors.ToList();
if (string.IsNullOrWhiteSpace(bookTitle))
{
throw new ArgumentNullException("Book Must Have Title!");
}
this.bookTitle = bookTitle;
if (authorList.Count() < 0)
{
throw new ArgumentNullException("You must provide at least one author!");
}
this.authors = new Authors(new List<Author>(authorList));
if (String.IsNullOrWhiteSpace(ISBN))
{
throw new ArgumentNullException("A Book Has to have an ISBN number. Check online or the back cover");
}
this.ISBN = ISBN;
if (numberofpages <= 0)
{
throw new ArgumentNullException("A Book has more than one page!");
}
this.numberofpages = numberofpages;
if (String.IsNullOrWhiteSpace(genre))
{
throw new ArgumentNullException("A Book has a genre. Find it and input it");
}
this.Genre = genre;
}
public override bool Equals(Object obj)
{
if (obj == null)
{
return false;
}
Book p = obj as Book;
if ((System.Object) p == null)
{
return false;
}
return (bookTitle == p.bookTitle) && (authors.Equals( p.authors)) && (numberofpages == p.numberofpages) &&
(ISBN == p.ISBN) && (Genre == p.Genre);
}
public bool Equals(Book p)
{
if ((object) p == null)
{
return false;
}
return (bookTitle == p.bookTitle) && (authors.Equals( p.authors)) && (numberofpages == p.numberofpages) &&
(ISBN == p.ISBN) && (Genre == p.Genre);
}
}
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestArea.Other
{
public class Author : IComparable<Author>
{
public string Name { get; set; }
public int CompareTo(Author other) => this.Name.CompareTo(other.Name);
}
public class Authors : ReadOnlyCollection<Author>, IEquatable<Authors>
{
public Authors(IList<Author> list) : base(list)
{
}
public bool Equals(Authors other)
{
//reference equal
if (other == this)
{
return true;
}
//No need to iterate over authors
if (other == null || other.Count != this.Count)
{
return false;
}
var thisSorted = this.ToArray();
var otherSorted = other.ToArray();
Array.Sort(thisSorted);
Array.Sort(otherSorted );
for (int i = 0; i < thisSorted.Length; i++)
{
if (thisSorted[i].CompareTo(otherSorted[i]) != 0)
{
return false;
}
}
return true;
}
}
public class Book : IEquatable<Book>
{
public string bookTitle { get; private set; }
public Authors authors { get; private set; }
public string ISBN { get; private set; }
public int numberofpages { get; private set; }
public string Genre { get; private set; }
//Made Authors parameter as simplified as it could be
public Book(string bookTitle, IEnumerable<Author> authors, string ISBN, int numberofpages, string genre)
{
var authorList = authors.ToList();
if (string.IsNullOrWhiteSpace(bookTitle))
{
throw new ArgumentNullException("Book Must Have Title!");
}
this.bookTitle = bookTitle;
if (authorList.Count() < 0)
{
throw new ArgumentNullException("You must provide at least one author!");
}
this.authors = new Authors(new List<Author>(authorList));
if (String.IsNullOrWhiteSpace(ISBN))
{
throw new ArgumentNullException("A Book Has to have an ISBN number. Check online or the back cover");
}
this.ISBN = ISBN;
if (numberofpages <= 0)
{
throw new ArgumentNullException("A Book has more than one page!");
}
this.numberofpages = numberofpages;
if (String.IsNullOrWhiteSpace(genre))
{
throw new ArgumentNullException("A Book has a genre. Find it and input it");
}
this.Genre = genre;
}
public override bool Equals(Object obj)
{
if (obj == null)
{
return false;
}
Book p = obj as Book;
if ((System.Object) p == null)
{
return false;
}
return (bookTitle == p.bookTitle) && (authors.Equals( p.authors)) && (numberofpages == p.numberofpages) &&
(ISBN == p.ISBN) && (Genre == p.Genre);
}
public bool Equals(Book p)
{
if ((object) p == null)
{
return false;
}
return (bookTitle == p.bookTitle) && (authors.Equals( p.authors)) && (numberofpages == p.numberofpages) &&
(ISBN == p.ISBN) && (Genre == p.Genre);
}
}
}
public static class IEnumerableExtensions
{
public static bool EqualTo<T>(this IEnumerable<T> enumerable, IEnumerable<T> other)
{
//reference equal
if (other == enumerable)
{
return true;
}
if (other == null)
{
return false;
}
var enumerableSorted = enumerable.ToArray();
var otherSorted = other.ToArray();
//No need to iterate over items if lengths are not equal
if (otherSorted.Length != enumerableSorted.Length)
{
return false;
}
Array.Sort(enumerableSorted);
Array.Sort(otherSorted);
return !enumerableSorted.Where((t, i) => t.Equals(otherSorted[i])).Any();
}
}
public override bool Equals(Object obj)
{
if (obj == null)
{
return false;
}
Book otherBook = obj as Book;
if ((System.Object) otherBook == null)
{
return false;
}
return (bookTitle == otherBook.bookTitle) &&
otherBook.authors.EqualTo(this.authors) &&
(numberofpages == otherBook.numberofpages) &&
(ISBN == otherBook.ISBN) &&
(Genre == otherBook.Genre);
}