StringDictionary vs Dictionary <cadena, cadena>

76

¿Alguien tiene alguna idea de cuáles son las diferencias prácticas entre el objeto System.Collections.Specialized.StringDictionary y System.Collections.Generic.Dictionary?

Los he usado en el pasado sin pensar mucho en cuál funcionaría mejor, funcionaría mejor con Linq o proporcionaría otros beneficios.

¿Alguna idea o sugerencia sobre por qué debería usar una sobre la otra?

Scott Ivey
fuente

Respuestas:

90

Dictionary<string, string>es un enfoque más moderno. Implementa IEnumerable<T>y es más adecuado para cosas LINQy.

StringDictionaryes la forma de la vieja escuela. Estaba allí antes de los días de los genéricos. Lo usaría solo cuando interactúe con código heredado.

mmx
fuente
Debe comparar para ver cuál funciona mejor para su situación especial. No espero una diferencia de rendimiento notable. Recomiendo usar Dictionary<string,string>para todo el código nuevo (a menos que necesite apuntar a 1.1).
mmx
2
@thecoop no tiene datos concretos para presentar de mi lado ahora, pero una vez, cuando realicé la prueba de velocidad, StringDictionaryfuncionó peor (aunque todo eso no importará principalmente). Para ser honesto, de hecho, antes tenía la noción de que StringDictionaryera una especie de colección especializada destinada a acelerar las cosas cuando stringera la clave, y para mi gran sorpresa cuando funcionó peor en mis pruebas, busqué en Google solo para descubrir que no es genérico
nawfal
1
@nawfal Creo que es más lento porque StringDictionary no distingue entre mayúsculas y minúsculas de forma predeterminada. Si crea un diccionario con un comparador de claves que no distingue entre mayúsculas y minúsculas, creo que el rendimiento será el mismo
phuclv
41

Otro punto.

Esto devuelve nulo:

StringDictionary dic = new StringDictionary();
return dic["Hey"];

Esto arroja una excepción:

Dictionary<string, string> dic = new Dictionary<string, string>();
return dic["Hey"];
Joshcomley
fuente
El "emite una excepción" característica de Dictionary<>los medios que nunca pueda usar []. Use StringDictionary ha limpiado gran parte de mi código.
James Curran
1
@James, llego un poco tarde, pero probablemente deberías usar TryGetValue.
Şafak Gür
@ ŞafakGür - Yo no utilizo TryGetValue () - porque nunca puedo utilizar [ ]ya que se produce una excepción. (StringDictionary solo resuelve esto para un tipo de diccionarios)
James Curran
@James, creo que lanzar una excepción para claves inexistentes es una mejor opción de API ya que se permite nulo como valor de diccionario. De esta forma, puede distinguir entre una clave que no existe y una cuyo valor es nulo.
Şafak Gür
1
@ ŞafakGür esto es cierto - si lo que necesita es un diccionario que a) siempre debe tener todos los valores, b) puede contener nulos yc) esos nulos significan algo diferente a "sin valor" .. Sin embargo, en un diccionario "no valor "suele representarse por la clave que no está allí. Sin embargo, la verdadera razón por la que Dictionary <> lanza una excepción es porque el valor podría ser un tipo de valor (y, por lo tanto, no se puede representar con un valor nulo).
James Curran
37

Como señaló Reed Copsey, StringDictionary reduce en minúsculas sus valores clave. Para mí, esto fue totalmente inesperado y es un obstáculo.

private void testStringDictionary()
{
    try
    {
        StringDictionary sd = new StringDictionary();
        sd.Add("Bob", "My name is Bob");
        sd.Add("joe", "My name is joe");
        sd.Add("bob", "My name is bob"); // << throws an exception because
                                         //    "bob" is already a key!
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Estoy agregando esta respuesta para llamar más la atención sobre esta gran diferencia, que en mi opinión es más importante que la diferencia moderna frente a la vieja escuela.

Jeff Roe
fuente
4
Si por alguna razón se desea el mismo comportamiento con Dictionary <string, string>, se puede utilizar: Dictionary <string, string> ht = new Dictionary <string, string> (StringComparer.OrdinalIgnoreCase); ht.Add ("Bob", "ff"); ht.Add ("bob", "ff"); // lanza una excepción
osexpert
36

Creo que StringDictionary es bastante obsoleto. Existía en la v1.1 del marco (antes de los genéricos), por lo que era una versión superior en ese momento (en comparación con el Diccionario no genérico), pero en este punto, no creo que tenga ventajas específicas. sobre Diccionario.

Sin embargo, StringDictionary tiene desventajas. StringDictionary reduce en minúsculas sus valores clave automáticamente, y no hay opciones para controlar esto.

Ver:

http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/59f38f98-6e53-431c-a6df-b2502c60e1e9/

Reed Copsey
fuente
2
StringDictionaryse puede utilizar Properites.Settingsmientras Dictionary<string,string>que no. Tan obsoleto o no, todavía tiene algún uso StringDictionary.
jahu
2

StringDictionary proviene de .NET 1.1 e implementa IEnumerable

Dictionary<string, string> proviene de .NET 2.0 e implementa IDictionary<TKey, TValue>,IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable

IgnoreCase solo está configurado para Key in StringDictionary

Dictionary<string, string> es bueno para LINQ

        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        dictionary.Add("ITEM-1", "VALUE-1");
        var item1 = dictionary["item-1"];       // throws KeyNotFoundException
        var itemEmpty = dictionary["item-9"];   // throws KeyNotFoundException

        StringDictionary stringDictionary = new StringDictionary();
        stringDictionary.Add("ITEM-1", "VALUE-1");
        var item1String = stringDictionary["item-1"];     //return "VALUE-1"
        var itemEmptystring = stringDictionary["item-9"]; //return null

        bool isKey = stringDictionary.ContainsValue("VALUE-1"); //return true
        bool isValue = stringDictionary.ContainsValue("value-1"); //return false
ArekBee
fuente
1

Además de ser una clase más "moderna", noté que Dictionary es más eficiente en memoria que StringDictionary por un amplio margen.

Daniel
fuente
11
Podríamos usar algunos números aquí
Zonko
1

Otro punto relevante es que (corrígeme si me equivoco aquí) System.Collections.Generic.Dictionaryno se puede usar en la configuración de la aplicación ( Properties.Settings) mientras System.Collections.Specialized.StringDictionaryque sí.

Matt Lyons
fuente