Подтвердить что ты не робот

Что является альтернативой словарям на С#, что позволяет дублировать ключи?

У меня есть метод, который возвращает группы техников, которые работали над определенными проектами, например:

project 1 | John
project 1 | Tim
project 2 | John
project 2 | Dave

Первоначально я пытался создать словарь, который обычно представляет собой коллекцию пар ключ-значение, но в этом случае я не могу использовать его, потому что у меня не может быть дублирующего ключа (проекта). Какую альтернативу я могу использовать?

Моя единственная мысль - создать Dictionary<Project, List<Technicians>>, но есть ли что-то намного проще?

4b9b3361

Ответ 1

В вашем случае тот же ключ связан с несколькими значениями, поэтому стандартный словарь не подходит, как есть. Вы можете объявить его как Dictionary<Key, List<Values>>.

Но также вы можете использовать:

Поиск, который

Представляет набор ключей, каждый из которых сопоставляется с одним или несколькими значениями.

Для этого нужна фреймворк 3.5 и более.

Ответ 2

Вам нужна связь между Project и одним или несколькими специалистами:

public class Project
{
    public ICollection<Technician> Technicians { get; set; }
}

var project = new Project();
project.Technicians = new List<Technician>()
{
    new Technician(),
    new Technician()
};

Ваши объекты должны отражать отношения в реальной жизни.

В качестве дополнительной заметки вам может быть интересно ознакомиться с дизайном, управляемым доменом.

public void LoadTechnicians(Project project)
{
    List<Technician> techs = new List<Technician>();

    // query the database and map Technician objects

    // Set the "Technicians" property
    project.Technicians = techs;
}

Ответ 4

Я не думаю, что в вашем решении есть что-то не так. В конце концов, вы можете легко получить доступ ко всем членам команды по проекту. Но вы можете попробовать List<KeyValuePair<Project, Technician>>. Вы поддерживаете отношение ключ-значение, но без ограничений не повторяющихся ключей. Это гораздо проще, чем у вас сейчас? Зависит от вариантов использования.

В качестве альтернативы вы можете скрыть эту структуру за своей реализацией пользовательской коллекции.

Ответ 5

Я скопировал свой собственный ответ из этого сообщения.

Это достаточно просто, чтобы "сворачивать свою собственную" версию словаря, которая допускает записи "дублировать ключ". Вот грубая простая реализация. Возможно, вы захотите рассмотреть возможность добавления поддержки для большинства (если не всех) в IDictionary<T>.

public class MultiMap<TKey,TValue>
{
    private readonly Dictionary<TKey,IList<TValue>> storage;

    public MultiMap()
    {
        storage = new Dictionary<TKey,IList<TValue>>();
    }

    public void Add(TKey key, TValue value)
    {
        if (!storage.ContainsKey(key)) storage.Add(key, new List<TValue>());
        storage[key].Add(value);
    }

    public IEnumerable<TKey> Keys
    {
        get { return storage.Keys; }
    }

    public bool ContainsKey(TKey key)
    {
        return storage.ContainsKey(key);
    }

    public IList<TValue> this[TKey key]
    {
        get
        {
            if (!storage.ContainsKey(key))
                throw new KeyNotFoundException(
                    string.Format(
                        "The given key {0} was not found in the collection.", key));
            return storage[key];
        }
    }
}

Быстрый пример того, как его использовать:

const string key = "supported_encodings";
var map = new MultiMap<string,Encoding>();
map.Add(key, Encoding.ASCII);
map.Add(key, Encoding.UTF8);
map.Add(key, Encoding.Unicode);

foreach (var existingKey in map.Keys)
{
    var values = map[existingKey];
    Console.WriteLine(string.Join(",", values));
}