it-swarm.com.de

Was ist eine Alternative zu Wörterbüchern in C #, die doppelte Schlüssel ermöglicht?

Ich habe eine Methode, die Gruppen von Technikern zurückgibt, die an bestimmten Projekten gearbeitet haben, zum Beispiel:

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

Ursprünglich habe ich versucht, ein Wörterbuch zu erstellen, das in der Regel meine bevorzugte Sammlung von Schlüsselwertpaaren ist. In diesem Fall kann ich es jedoch nicht verwenden, da ich keinen doppelten Schlüssel (das Projekt) haben kann. Was ist eine Alternative, die ich verwenden kann?

Mein einziger Gedanke ist, einen Dictionary<Project, List<Technicians>> zu erstellen, aber ist da etwas einfacher?

31
AdamMc331

In Ihrem Fall ist derselbe Schlüssel mit multiple -Werten verknüpft, sodass das Standardwörterbuch nicht geeignet ist. Sie können es wie Dictionary<Key, List<Values>> deklarieren.

Sie können aber auch Folgendes verwenden:

Lookup Klasse, das ist 

Stellt eine Sammlung von Schlüsseln dar, die jeweils einem oder mehreren Werten zugeordnet sind.

Dafür benötigen Sie das Framework 3.5 und mehr.

44
Tigran

Was Sie brauchen, ist eine Beziehung zwischen einer Project und einem oder mehreren Technikern:

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

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

Ihre Objekte sollten die Beziehungen im wirklichen Leben widerspiegeln.

Als Randnotiz möchten Sie vielleicht über Domänengesteuertes Design lesen.

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;
}
13
Greg Burghardt

Es gibt ein experimentelles NuGet-Paket von MS, das MultiValueDictionary enthält.

Im Grunde ist es wie Dictionary<Project, List<Technicians>>, außer dass Sie nicht jedes Mal die Logik wiederholen müssen, um die Lists bei jedem Zugriff zu verwalten.

12
svick

Ich glaube nicht, dass mit Ihrer Lösung etwas nicht stimmt. Nach all dem können Sie problemlos auf alle Teammitglieder nach Projekt zugreifen. Alternativ können Sie auch List<KeyValuePair<Project, Technician>> versuchen. Sie pflegen die Schlüssel-Wert-Beziehung, jedoch ohne Einschränkung nicht wiederholter Schlüssel. Ist es viel einfacher zu dem, was Sie jetzt haben? Abhängig von Anwendungsfällen.

Alternativ können Sie diese Struktur hinter Ihrer benutzerdefinierten Sammlungsimplementierung ausblenden.

4
PiotrWolkowski

Ich habe meine eigene Antwort aus diesem Beitrag kopiert.

Es ist leicht genug, Ihre eigene Version eines Wörterbuchs zu "rollen", die "doppelte Schlüsseleinträge" zulässt. Hier ist eine grobe einfache Implementierung. Möglicherweise möchten Sie die Unterstützung für die meisten (wenn nicht alle) für IDictionary<T> hinzufügen.

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];
        }
    }
}

Ein schnelles Beispiel zur Verwendung:

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));
}
0
ChristopheD