Словарь C #: каждый ключ имеет идентичное значение - могу ли я удалить избыточность? - PullRequest
1 голос
/ 03 декабря 2009

Рассмотрим следующий код, где каждый ключ имеет одинаковое значение:

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

Мой вопрос:

  • Могу ли я удалить избыточность, чтобы мне не приходилось повторять каждый строка дважды, похожая на следующее:
IDictionary<string, string> quarterbackDictionary = new Dictionary<string, string>();
quarterbackDictionary.Add("Manning");
quarterbackDictionary.Add("Brady");
quarterbackDictionary.Add("Rivers");

FYI:

  • Я использую словарь, потому что хочу добавить попытку вставить дубликат ключа.
  • HashSet будет не выдавать попытку вставить дубликат ключа.

Ответы [ 5 ]

11 голосов
/ 03 декабря 2009

Вы можете обернуть 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).

3 голосов
/ 03 декабря 2009

Добавьте метод расширения в HashSet, скажем, AddUnique, который просто вызывает Add и выдает, если return равен false.

1 голос
/ 03 декабря 2009

Вы также можете наследовать от 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
1 голос
/ 03 декабря 2009

Возможно, вы могли бы использовать метод расширения

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);
    }
}
1 голос
/ 03 декабря 2009

Наследовать от System.Collections.ObjectModel.Collection и переопределять InsertItem (который защищен).

Затем вы можете выполнить проверку дубликатов, когда кто-то вставляет дубликат. InsertItem вызывается для любого из методов, которые могут добавить новый элемент: Добавить, Вставить и т. Д.

...