Domanda

Qual è il modo più efficiente per creare una costante (non cambia mai in fase di esecuzione) da string sa int s?

Ho provato a utilizzare un const Dictionary , ma non ha funzionato.

Potrei implementare un wrapper immutabile con la semantica appropriata, ma ciò non sembra ancora del tutto corretto.


Per coloro che hanno chiesto, sto implementando IDataErrorInfo in una classe generata e sto cercando un modo per rendere la ricerca columnName nel mio array di descrittori.

Non ero a conoscenza (errore di battitura durante il test! d'oh!) che switch accetta le stringhe, quindi è quello che userò. Grazie!

È stato utile?

Soluzione

La creazione di un dizionario costante generato in fase di compilazione in C # non è un compito semplice. In realtà, nessuna delle risposte qui lo raggiunge davvero.

Esiste però una soluzione che soddisfa le tue esigenze, sebbene non necessariamente una buona soluzione; ricorda che secondo la specifica C #, le tabelle di switch-case vengono compilate in tabelle di hash jump costanti. Cioè, sono dizionari costanti, non una serie di istruzioni if-else. Quindi considera un'istruzione switch-case come questa:

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

Questo è esattamente quello che vuoi. E sì, lo so, è brutto.

Altri suggerimenti

Esistono poche preziose collezioni immutabili nel quadro attuale. Posso pensare a un'opzione relativamente indolore in .NET 3.5:

Usa Enumerable.ToLookup() - la Lookup<,> è immutabile (ma multivalore su rhs); puoi farlo da un Dictionary<,> abbastanza facilmente:

    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();
enum Constants
{
    Abc = 1,
    Def = 2,
    Ghi = 3
}

...

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

Questa è la cosa più vicina ad un " Dizionario CONST " ;:

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

Il compilatore sarà abbastanza intelligente da creare il codice il più pulito possibile.

Se utilizzassi 4.5+ utilizzerei ReadOnlyDictionary (anche ReadOnly Collection per elenchi) per eseguire mappature / costanti di sola lettura. È implementato nel modo seguente.

static class SomeClass
{
    static readonly ReadOnlyDictionary<string,int> SOME_MAPPING 
        = new ReadOnlyDictionary<string,int>(
            new Dictionary<string,int>()
            {
                { "One", 1 },
                { "Two", 2 }
            }
        )
}        

Perché non usare spazi dei nomi o classi per nidificare i tuoi valori? Potrebbe essere imperfetto, ma è molto pulito.

public static class ParentClass
{
    // here is the "dictionary" class
    public static class FooDictionary
    {
        public const string Key1 = "somevalue";
        public const string Foobar = "fubar";
    }
}

Ora puoi accedere a .ParentClass.FooDictionary.Key1, ecc.

Non sembra esserci alcuna interfaccia standard immutabile per i dizionari, quindi la creazione di un wrapper sembra purtroppo l'unica opzione ragionevole.

Modifica : Marc Gravell ha trovato ILookup che mi mancava, che ti consentirà almeno di evitare di creare un nuovo wrapper, anche se devi ancora trasformare il Dizionario con .ToLookup ().

Se questa è una necessità limitata a uno scenario specifico, potresti stare meglio con un'interfaccia più orientata alla logica di business:

interface IActiveUserCountProvider
{
    int GetMaxForServer(string serverName);
}

Perché no:

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>>(); }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top