Pregunta

¿Cuál es la forma más eficiente de crear una asignación constante (nunca cambia en tiempo de ejecución) de string sa int s?

He intentado usar un Diccionario const , pero eso no funcionó.

Podría implementar un envoltorio inmutable con la semántica adecuada, pero eso todavía no parece totalmente correcto.


Para aquellos que han preguntado, estoy implementando IDataErrorInfo en una clase generada y estoy buscando una manera de hacer que el columnName busque en mi conjunto de descriptores.

No sabía (error tipográfico al probar! d'oh!) que el interruptor acepta cadenas, así que eso es lo que voy a usar. Gracias!

¿Fue útil?

Solución

Crear un diccionario constante realmente generado en tiempo de compilación en C # no es realmente una tarea sencilla. En realidad, ninguna de las respuestas aquí realmente logra eso.

Sin embargo, existe una solución que cumple con sus requisitos, aunque no necesariamente una buena; recuerde que de acuerdo con la especificación de C #, las tablas de mayúsculas y minúsculas se compilan en tablas de salto hash constantes. Es decir, son diccionarios constantes, no una serie de declaraciones if-else. Considere una declaración de cambio de caso como esta:

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

Esto es exactamente lo que quieres. Y sí, lo sé, es feo.

Otros consejos

Hay muy pocas colecciones inmutables en el marco actual. Puedo pensar en una opción relativamente indolora en .NET 3.5:

Use Enumerable.ToLookup() - la Lookup<,> clase es inmutable (pero multivalorizado en el rhs); puedes hacer esto desde un Dictionary<,> con bastante facilidad:

    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");

Esto es lo más parecido a un " Diccionario CONST " ;:

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

El compilador será lo suficientemente inteligente como para construir el código lo más limpio posible.

Si usara 4.5+ Framework, usaría ReadOnlyDictionary (también ReadOnly Collection para listas) para hacer asignaciones / constantes de solo lectura. Se implementa de la siguiente manera.

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

¿Por qué no usar espacios de nombres o clases para anidar sus valores? Puede ser imperfecto, pero está muy limpio.

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

Ahora puede acceder a .ParentClass.FooDictionary.Key1, etc.

Parece que no existe una interfaz inmutable estándar para los diccionarios, por lo que, desafortunadamente, la creación de un contenedor parece ser la única opción razonable.

Editar : Marc Gravell encontró la ILookup que me perdí, que le permitirá al menos evitar crear un nuevo contenedor, aunque aún necesita transformar el Diccionario con .ToLookup ().

Si esta es una necesidad restringida a un escenario específico, es mejor que tenga una interfaz más orientada a la lógica empresarial:

interface IActiveUserCountProvider
{
    int GetMaxForServer(string serverName);
}

¿Por qué 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>>(); }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top