What is the correct exception to throw in the following instance?
If, for example, I have a class: Album with a collection of Songs:
List<Song>
And a method within Album to add a Song:
public void AddSong(Song song)
{
songs.Add(song);
}
Should I throw an exception if a user attempts to add a song that already exists? If so, what type of exception?
I have heard the phrase: “Only use exceptions in exceptional circumstances”, but I want to tell the client implementing Album exactly what has gone wrong (not just return a Boolean value).
If your use case implies that items in the collection should be unique, then you should use a datastructure that enforces that.
By doing that, you not only avoid having to write a O(N) lookup method to check for duplicates, but you can also bubble up the pre-existing duplicate key exception that a collection of this sort would throw.
However, .NET does not have a distinct collection that preserves sort order, though it is very easy to extend List to support this.
The approach I used below sacrifices memory footprint for speed, by storing the unique values in a second HashSet. If memory size was more important, you’d just have to do a O(N) check on each Add operation. Because methods are not virtual (for some reason) in List, I resulted to hiding the base methods using the new keyword.
Note that this is just an example, and is not thread safe, and should probably not be used in a real production application.