2008-11-06 12 views
88

Was ist die effizienteste Möglichkeit, eine Konstante (ändert sich nie zur Laufzeit) Mapping von string s zu int s?Erstellen einer Konstante Dictionary in C#

Ich habe versucht mit einer const Dictionary, aber das hat nicht geklappt.

Ich könnte eine immutable wrapper mit entsprechender Semantik implementieren, aber das scheint immer noch nicht völlig richtig.


Für diejenigen, die darum gebeten haben, ich IDataErrorInfo in einer generierten Klasse und ist auf der Suche nach einem Weg bin die Umsetzung die column Lookup in meine Reihe von Deskriptoren zu machen.

Ich war mir nicht bewusst (Tippfehler beim Testen! D'oh!), Dass Schalter Strings akzeptiert, also werde ich das verwenden. Vielen Dank!

+0

es eine Lösung ist hier: http://stackoverflow.com/questions/10066708/readonly-keyword-does-not-make-a-list-readonly –

Antwort

132

Erstellen einer wirklich kompilieren-Zeitkonstante Wörterbuch in C# erzeugt wird, nicht wirklich eine einfache Aufgabe ist. Tatsächlich erreicht keine der Antworten das wirklich.

Es gibt jedoch eine Lösung, die Ihren Anforderungen entspricht, aber nicht unbedingt eine nette; Beachten Sie, dass gemäß der C# -Spezifikation Switch-Case-Tabellen in konstante Hash-Jump-Tabellen kompiliert werden. Das heißt, sie sind konstante Wörterbücher, keine Folge von if-else-Anweisungen. Überlegen Sie sich eine solche Anweisung:

switch (myString) 
{ 
    case "cat": return 0; 
    case "dog": return 1; 
    case "elephant": return 3; 
} 

Dies ist genau das, was Sie wollen. Und ja, ich weiß, es ist hässlich.

+17

Hey, ich habe gerade etwas gelernt. – mackenir

+7

Es ist sowieso Code generiert, hat gute Leistungsmerkmale, kann compile-time berechnet werden, und hat auch andere schöne Eigenschaften für meinen Anwendungsfall. Ich werde es so machen! –

+4

seien Sie vorsichtig, dass das Zurückgeben von Nicht-Wert-Typen, auch wenn dies die Klassenimmutierbarkeit bricht. –

1

Es scheint keine standardmäßige unveränderliche Schnittstelle für Wörterbücher zu geben, daher scheint die Erstellung eines Wrappers leider die einzig vernünftige Option zu sein.

Bearbeiten: Marc Gravell hat den ILookup gefunden, den ich vermisst habe - damit Sie zumindest vermeiden können, einen neuen Wrapper zu erstellen, obwohl Sie das Dictionary immer noch mit .ToLookup() umwandeln müssen.

interface IActiveUserCountProvider 
{ 
    int GetMaxForServer(string serverName); 
} 
31

Es gibt sehr wenige unveränderlichen Sammlungen im aktuellen Rahmen:

Wenn dies eine Notwendigkeit, ein bestimmtes Szenario beschränkt ist, können Sie mit einer Business-Logik-orientierte Schnittstelle besser dran. Ich kann an eine relativ schmerzfreie Option in .NET denken 3.5:

Verwendung Enumerable.ToLookup() - die Lookup<,> Klasse ist unveränderlich (aber mehrwertig auf der RH); Sie können aus einer Dictionary<,> dies tun, ganz einfach:

Dictionary<string, int> ids = new Dictionary<string, int> { 
     {"abc",1}, {"def",2}, {"ghi",3} 
    }; 
    ILookup<string, int> lookup = ids.ToLookup(x => x.Key, x => x.Value); 
    int i = lookup["def"].Single(); 
12
enum Constants 
{ 
    Abc = 1, 
    Def = 2, 
    Ghi = 3 
} 

... 

int i = (int)Enum.Parse(typeof(Constants), "Def"); 
+1

Interessante Idee! Ich frage mich, wie gut der Aufruf von Parse() funktioniert. Ich fürchte nur ein Profiler kann das beantworten. –

9

Dies ist die nächste Sache, die Sie zu einem „CONST-Wörterbuch“ bekommen:

public static int GetValueByName(string name) 
{ 
    switch (name) 
    { 
     case "bob": return 1; 
     case "billy": return 2; 
     default: return -1; 
    } 
} 

Der Compiler wird klug genug sein, den Code so sauber wie möglich zu bauen.

0

Warum nicht:

public class MyClass 
{ 
    private Dictionary<string, int> _myCollection = new Dictionary<string, int>() { { "A", 1 }, { "B", 2 }, { "C", 3 } }; 

    public IEnumerable<KeyValuePair<string,int>> MyCollection 
    { 
     get { return _myCollection.AsEnumerable<KeyValuePair<string, int>>(); } 
    } 
}
+2

Weil dies im Vergleich zu den verfügbaren Alternativen unter den angegebenen Bedingungen ziemlich teuer ist. –