I want to use a HashSet but worry that it "silently" absorbs duplicates (by returning true/false) but not by throwing an Exception. I'm interested in an equivalent data structure that does throw an exception (like a Dictionary would).
What's the best approach for this?
You can just define an extension method on HashSet<T>
(and trust it a bit more not to have to).
public static class Extensions {
public static void AddWithThrow<T>(this HashSet<T> hashSet, T value) {
if (hashSet.Add(value) == false) {
throw new ArgumentException("An item with the same value has already been added");
}
}
}
and if for some reason you had an ICollection<T>
accepting method that wants throwing semantics on Add
, maybe this:
public class ThrowingHashSet<T> : HashSet<T>, ICollection<T> {
// uncomment if you can live with the confusion
// of HashSet<T> variables and HashSet<T> accepting methods
// calling the existing HashSet<T>.Add non-throwing method instead
// public new void Add(T value) => AddWithThrow(value);
private void AddWithThrow(T value) {
if (base.Add(value) == false) {
throw new ArgumentException("An item with the same value has already been added");
}
}
void ICollection<T>.Add(T item) => this.AddWithThrow(item);
}