Ich plane, mehrere Namen-indizierte Wörterbücher in einem Projekt zu verwenden. Meine erste Wahl war die Verwendung eines Schlüssels string
, der nur die Name-Eigenschaft meiner Value
Elemente ist.Typ Sicherheit für Dictionary-Schlüssel?
Allerdings macht dies der Dictionary-Schlüssel identisch, obwohl sie verschiedene Arten zugreifen:
private Dictionary<string, Foo> myFoos;
private Dictionary<string, Bar> myBars;
myFoos[bar.Name]; // shouldn't be able to do this!
würde ich die Schlüssel wie Typ-nicht miteinander kompatibel sein, um sie unmöglich zu machen, miteinander zu verwechseln:
private Dictionary<FooName, Foo> myFoos;
private Dictionary<BarName, Bar> myBars;
Da eine *Name
Klasse für jede Value
Art zu schaffen Overkill ist, habe ich eine Name<T>
Klasse:
public struct Name<T>
{
public string Name;
// for convenience, could be explicit instead
static implicit operator string(Name<T> name)
{
return name.Name;
}
}
die mir
private Dictionary<Name<Foo>, Foo> myFoos;
private Dictionary<Name<Bar>, Bar> myBars;
geben würde, und dann konnte ich Name<Foo>
Instanzen anstelle von Strings speichern.
Das scheint ein bisschen unhandlich, aber es ist das Beste, was ich bisher gefunden habe - irgendwelche Vorschläge, wie man es besser macht?
Ist das fehlgeleitet oder genial?
Das Problem tritt auf, wenn ich die Liste der Bars, die einem Foo gehören, speichern möchte. Anstatt eine zweite Kopie der Bars zu speichern, speichere ich die Bar.Name - und eine Dictionary> beginnt zu schlammigen Gewässern. –
mskfisher
@mskfisher: das ist ein schlechter Ansatz. * Speichern Sie die Bars direkt, nicht nur ihre Namen! Das ist * nicht * das Erstellen von Kopien (es sei denn, Ihre Foos und Bars sind Strukturen, die sie in diesem Fall nicht sein sollten). Wenn es sich um Klassen handelt, werden Ihre Kopien keine Kopien erstellen, sondern nur Verweise auf die Objekte. Dies ist eine fundamentale Eigenschaft der Objektorientierung und Ihr Anwendungsfall ist so üblich, dass er einen eigenen Namen hat: [aggregation] (http://en.wikipedia.org/wiki/Object_composition). –
@Konrad: Guter Fang, und eine andere Sache hätte ich erwähnen sollen. Ich habe bei diesem Design zwischen Structs und Klassen hin und her gegangen, da ich Kopien zwischen Threads nach Wert, nicht nach Referenz übergeben möchte. Ich bin jetzt dabei, nur mit Klassen zu gehen und den Kopierkonstruktor für jeden Typ zu erstellen, den ich zwischen Threads übergeben muss. – mskfisher