Home Overriding the .Add method in a List of... with validation
Reply: 3

Overriding the .Add method in a List of... with validation

CB Du Rietz
1#
CB Du Rietz Published in 2017-12-07 23:03:11Z

I have a Use Case where I want to validate a specific property in a list of objects to make sure it is unique. The basic setting can be seen in the code below.

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

Now, in the code above, adding a new Book in the List of Books should throw an exception if the ISBN number isn't unique.

I would like to extend on the .Add method of the List and add that validation, but I'm not sure how to actually do that.

I've seen similar things, but they all assume that the Directory inherits from List and you write an overriding .Add method to the Directory - which doesn't look like a valid solution in this case.

Perhaps my general approach is backwards?

Please advice.

InBetween
2#
InBetween Reply to 2017-12-07 23:45:39Z

If you want uniqueness, use a collection that gives you that: a set.

Make an IEqualityComparer<book> that considers two books to be equal if the Isbns match and use it in a HashSet<Book> that represents your unique list of books:

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

And you are done, you can't have any duplicate books in Books.

Julian
3#
Julian Reply to 2017-12-07 23:08:04Z

One option is to create a new class and inherit from Collection<T> instead of List<T>, where you could overwrite InsertItem

e.g.

public class MyList: Collection<string>
{

    protected override void InsertItem(int index, string newItem)
    {
        DoValidation();
    }

}

called with the following call:

var myList = new MyList();
myList.Add("item1");
Dave
4#
Dave Reply to 2017-12-07 23:24:19Z

Why not this?

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
}
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.308568 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO