C# 正在覆盖列表中的.Add方法。。。经过验证

C# 正在覆盖列表中的.Add方法。。。经过验证,c#,.net,C#,.net,我有一个用例,我想验证对象列表中的特定属性,以确保它是唯一的。基本设置可以在下面的代码中看到 class Program { static void Main(string[] args) { Directory myDirectory = new Directory("Interaction Design"); myDirectory.Books.Add(new Book("978-0-262-64037-4", "The Design of Ever

我有一个用例,我想验证对象列表中的特定属性,以确保它是唯一的。基本设置可以在下面的代码中看到

class Program {
    static void Main(string[] args) {

        Directory myDirectory = new Directory("Interaction Design");
        myDirectory.Books.Add(new Book("978-0-262-64037-4", "The Design of Everyday Things")); //Should be added
        myDirectory.Books.Add(new Book("978-0-262-13474-3", "Designing Interactions")); //Should be added
        myDirectory.Books.Add(new Book("978-0-262-13474-3", "Whoops, I slipped up")); //Should NOT be added

    }
}

public class Directory {
    public Directory(string name) {
        Name = name;
    }
    public string Name { get; set; }
    public List<Book> Books { get; set; } = new List<Book>();
}

public class Book {
    public Book(string isbn, string title) {
        Isbn = isbn;
        Title = title;
    }
    public string Title { get; set; }
    public string Isbn { get; set; }
}
类程序{
静态void Main(字符串[]参数){
目录myDirectory=新目录(“交互设计”);
myDirectory.Books.Add(新书(“978-0-262-64037-4”,“日常用品的设计”);//应该添加
myDirectory.Books.Add(新书(“978-0-262-13474-3”,“设计交互”);//应添加
myDirectory.Books.Add(新书(“978-0-262-13474-3”,“哎呀,我搞错了”);//不应添加
}
}
公共类目录{
公用目录(字符串名称){
名称=名称;
}
公共字符串名称{get;set;}
公共列表书籍{get;set;}=new List();
}
公共课堂用书{
公共图书(字符串isbn,字符串标题){
Isbn=Isbn;
头衔=头衔;
}
公共字符串标题{get;set;}
公共字符串Isbn{get;set;}
}
现在,在上面的代码中,如果ISBN编号不是唯一的,那么在图书列表中添加新书将引发异常

我想扩展列表的.Add方法并添加验证,但我不确定实际如何做

我见过类似的情况,但它们都假设目录继承自列表,并且您编写了一个覆盖的.Add方法到目录中-在本例中,这看起来不是一个有效的解决方案

也许我的一般方法是倒退的


请注意。

一个选项是创建一个新类并从
集合继承,而不是从
列表继承,您可以在其中覆盖

e、 g

为什么不是这个

public class Directory
{
    private List<Book> _books;

    public IEnumerable<Book> Books
    {
        {
             return _books;
        }
    }

    Public void AddBook(Book book)
    {
         //Validate 
        if(valid)
        {
            _books.Add(book);
        }
    }
    //Etc
}
公共类目录
{
私人书单;
公共数字图书
{
{
还书;
}
}
公共无效地址簿(Book Book)
{
//证实
如果(有效)
{
_图书。添加(图书);
}
}
//等
}

如果您想要唯一性,请使用一个集合,该集合为您提供:一个集合

制作一个
IEqualityComparer
,如果ISBN匹配,则认为两本书相等,并将其用于表示唯一图书列表的
HashSet

public class Directory 
{

    public HashSet<Book> Books { get; } 
        = new HashSet<Book>(new BookEqualityComparer());
    //...
    private class BookEqualityComparer : IEqualityComparer<Book>
    {
        public bool Equals(Book x, Book y)
        {
            if (ReferenceEquals(x, y))
                return true;

            if (ReferenceEquals(x, null) ||
                ReferenceEquals(y, null))
                return false;

            return x.Isbn == y.Isbn;
        }

        public int GetHashCode(Book obj)
            => obj.Isbn.GetHashCode();
    }
}
公共类目录
{
公共哈希集书籍{get;}
=新哈希集(new BookEqualityComparer());
//...
私有类BookEqualityComparer:IEqualityComparer
{
公共布尔等于(第x册,第y册)
{
if(ReferenceEquals(x,y))
返回true;
if(ReferenceEquals(x,null)||
ReferenceEquals(y,null))
返回false;
返回x.Isbn==y.Isbn;
}
public int GetHashCode(Book obj)
=>obj.Isbn.GetHashCode();
}
}

完成后,在
图书中不能有任何重复的图书

请参见此链接,将图书列表设置为私有。使用IEnumerable getter公开它,然后使用add and remove方法进行验证,然后将其添加到私有列表或将其删除?我已经看到了这两个问题,但从来没有在验证部分本身找到任何解决方案。我认为最好的方法是将Books属性拆分为一个类。有一个专门针对这种情况构建的解决方案。这似乎是最实际的解决方案,将Books属性拆分为一个自己的类,并对其进行操作。我希望避免这种情况,但如果这是我最好的选择……那真是一种很好的解决问题的方法。它正在运行。谢谢
public class Directory
{
    private List<Book> _books;

    public IEnumerable<Book> Books
    {
        {
             return _books;
        }
    }

    Public void AddBook(Book book)
    {
         //Validate 
        if(valid)
        {
            _books.Add(book);
        }
    }
    //Etc
}
public class Directory 
{

    public HashSet<Book> Books { get; } 
        = new HashSet<Book>(new BookEqualityComparer());
    //...
    private class BookEqualityComparer : IEqualityComparer<Book>
    {
        public bool Equals(Book x, Book y)
        {
            if (ReferenceEquals(x, y))
                return true;

            if (ReferenceEquals(x, null) ||
                ReferenceEquals(y, null))
                return false;

            return x.Isbn == y.Isbn;
        }

        public int GetHashCode(Book obj)
            => obj.Isbn.GetHashCode();
    }
}