Question

Consider the following code, where each key has an identical value:

IDictionary<string, string> quarterbackDictionary = new Dictionary<string, string>();
quarterbackDictionary.Add("Manning", "Manning");
quarterbackDictionary.Add("Brady", "Brady");
quarterbackDictionary.Add("Rivers", "Rivers");

My question:

  • Can I remove the redundancy, so that I don't have to repeat each string twice, similar to the following:
IDictionary<string, string> quarterbackDictionary = new Dictionary<string, string>();
quarterbackDictionary.Add("Manning");
quarterbackDictionary.Add("Brady");
quarterbackDictionary.Add("Rivers");

FYI:

  • I'm using a Dictionary because I want to throw on an attempt to insert a duplicate key.
  • A HashSet would not throw on an attempt to insert a duplicate key.
Was it helpful?

Solution

Perhaps you could use an extension method

public static class DictionaryExtensions
{
    public static void Add(this Dictionary<string, string> dictionary,  
        string keyAndValue)
    {
        string value;
        if (dictionary.TryGetValue(keyAndValue, out value))
        {
            throw new Exception();
        }

        dictionary.Add(keyAndValue, keyAndValue);
    }
}

OTHER TIPS

You could wrap a HashSet<string> in your own class, and have it throw an exception if you try to add the same key twice.

It won't be much trouble to define that class, in fact, here is a possible implementation that you can tweak to fit your needs:

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

As the other answers mention, you could also make it an extension method. I think you could certainly do this, unless you need to be absolutely sure that you cannot add the same item twice (if you do it the extension method way, one could still call the regular .Add method).

Add an extension method to HashSet, say AddUnique, which just calls Add and throws if the return is false.

Inherit from System.Collections.ObjectModel.Collection and override InsertItem (which is protected).

Then you can do your duplicate check and throw when someone inserts a duplicate item. InsertItem is called on any of the methods that can put in a new item: Add, Insert, etc.

You could also inherit from System.Collections.ObjectModel.KeyedCollection.

class MyDictionary : KeyedCollection<string, string>
{
    protected override string GetKeyForItem(string item)
    {
        return item;
    }
}

var d = new MyDictionary();
d.Add("jones");
d.Add("jones");   // this will except
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top