Вы можете обернуть HashSet в своем собственном классе и получить исключение, если попытаетесь добавить один и тот же ключ дважды.
Определить этот класс не составит большого труда, на самом деле, вот возможная реализация, которую вы можете настроить в соответствии со своими потребностями:
public class UniqueHashSet<T> : ICollection<T>
{
private readonly HashSet<T> innerSet = new HashSet<T>();
public void Add(T item)
{
if (innerSet.Contains(item))
throw new ArgumentException("Element already exists", "item");
innerSet.Add(item);
}
public void Clear()
{
innerSet.Clear();
}
public bool Contains(T item)
{
return innerSet.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
innerSet.CopyTo(array, arrayIndex);
}
public bool Remove(T item)
{
return innerSet.Remove(item);
}
public int Count
{
get { return innerSet.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public IEnumerator<T> GetEnumerator()
{
return innerSet.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return innerSet.GetEnumerator();
}
}
Как уже упоминалось в других ответах, вы также можете сделать это методом расширения. Я думаю, что вы, безусловно, могли бы сделать это, если только вам не нужно быть абсолютно уверенным, что вы не можете добавить один и тот же элемент дважды (если вы сделаете это методом расширения, можно все равно вызвать обычный метод .Add).