我有以下类,使用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 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
}
我的问题:
这两种方法都会评估为false,因为我在构造函数中指定作者之前创建了一个新的List:
this.authors = new ReadOnlyCollection<Author>(new List<Author>(authors));
我这样做是为了让用户无法对课程外的ReadOnlyCollection
进行更改。所做的任何更改都将在该集合的副本上。考虑到这一点,鉴于我创建了一个新列表,如何让我的Equals方法正常工作?
答案 0 :(得分:1)
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);
}
}
}
通用IEnumerable Equality方法:
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);
}
答案 1 :(得分:0)
您的图书课程可以/应该实施IComparable和IEquatable。您可能还希望将收藏集分类为Sort ObservableCollection<string> C#。如果没有更多信息,很难推荐一个坚如磐石的答案,但如果你查看我所做的链接/建议,你可能会在你的项目上取得很好的进展。