StringD Dictionary vs Dictionary <рядок, рядок>


76

Хтось уявляє, які практичні відмінності існують між об'єктом System.Collections.Specialized.StringDictionary та System.Collections.Generic.Dictionary?

Раніше я використовував їх обох, не надто замислюючись про те, які ефективніші результати, краща робота з Linq чи надання будь-яких інших переваг.

Будь-які думки чи пропозиції щодо того, чому я повинен використовувати одне над іншим?

Відповіді:


90

Dictionary<string, string>є більш сучасним підходом. Це реалізує, IEnumerable<T>і це більше підходить для речей LINQy.

StringDictionaryце стара школа. Це було до днів генериків. Я б використовував його лише при взаємодії зі застарілим кодом.


Вам слід порівняти, щоб побачити, які ефективніші ефективні для вашої особливої ​​ситуації. Я не очікую помітної різниці в продуктивності. Я рекомендую використовувати Dictionary<string,string>для всього нового коду (якщо вам не потрібно націлити 1.1).
mmx

2
@thecoop з мого боку зараз не представляє жодних жорстких даних, але колись, коли я робив тест на швидкість, StringDictionaryпрацював гірше (хоча все це, як правило, не має значення). Чесно кажучи, насправді, раніше у мене було уявлення, що StringDictionaryце якась спеціалізована колекція, призначена для пришвидшення роботи, коли це stringбуло ключовим фактором, і, на моє велике здивування, коли вона мала гірші результати в моєму тестуванні, я погуглив її лише для того, щоб зрозуміти, що вона не є загальною
nawfal

1
@nawfal Я думаю, що це повільніше, оскільки StringDictionary за замовчуванням не враховує регістр. Якщо ви створите словник із порівнянням клавіш, що не враховує регістр, тоді я вважаю, що продуктивність буде однаковою
phuclv

41

Ще один момент.

Це повертає null:

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

Це видає виняток:

Dictionary<string, string> dic = new Dictionary<string, string>();
return dic["Hey"];

«Кидає виняток» особливість з Dictionary<>коштів я не можу використовувати []. Використання StringDictionary очистило значну частину мого коду.
James Curran

1
@James Я трохи запізнився, але, мабуть, варто скористатися TryGetValue.
faafak Gür

@ ŞafakGür - Я дійсно використовувати TryGetValue () - тому що я ніколи не можу використовувати , [ ]тому що він викликає виключення. (StringDictionary вирішує це лише для одного типу Словників)
James Curran

@James, я вважаю, що додавання винятку для неіснуючих ключів є кращим вибором API, оскільки null дозволено як значення словника. Таким чином ви можете розрізнити неіснуючий ключ від ключа, значення якого дорівнює нулю.
faafak Gür

1
@ ŞafakGür це правда - якщо вам потрібен словник, який а) повинен завжди мати всі значення, б) може містити нулі та в) ці нулі означають щось інше, ніж "немає значення". Однак у словнику "ні значення "зазвичай представляється ключем, якого немає. Однак справжньою причиною, за якою словник <> видає виняток, є те, що значення може бути типом значення (і, отже, не може бути представлене нулем).
James Curran

37

Як зазначав Рід Копсі, StringDictionary малі ваші ключові значення. Для мене це було абсолютно несподівано і є шоу-пробкою.

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

Я додаю цю відповідь, щоб привернути більше уваги до цієї величезної різниці, яка ІМО є важливішою, ніж різниця між сучасною та старою школою.


4
Якщо з якихось причин хочеться однакової поведінки зі словником <рядок, рядок>, це можна використовувати: Словник <рядок, рядок> ht = новий словник <рядок, рядок> (StringComparer.OrdinalIgnoreCase); ht.Add ("Боб", "ff"); ht.Add ("bob", "ff"); // кидає виняток
osexpert

36

Я думаю, що StringDictionary є майже застарілим. Він існував у v1.1 фреймворку (до дженериків), тому на той час він був вищою версією (порівняно із невзагальненим словником), але на даний момент я не вірю, що в ньому є якісь конкретні переваги над Словником.

Однак у StringDictionary є і недоліки. StringDictionary низькі регістри ваших ключових значень автоматично, і немає варіантів керування цим.

Подивитися:

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


2
StringDictionaryможе використовуватися в Properites.Settingsтой час як Dictionary<string,string>не може. Настільки застарілі чи ні, для них все ж є певна користь StringDictionary.
джаху

2

StringDictionary походить із .NET 1.1 і реалізує IEnumerable

Dictionary<string, string> походить із .NET 2.0 і реалізує IDictionary<TKey, TValue>,IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable

IgnoreCase встановлено лише для Key in StringDictionary

Dictionary<string, string> добре для 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

1

Окрім того, що я є більш "сучасним" класом, я помітив, що "Словник" з більшим запасом ефективніше пам'яті, ніж StringDictionary.


11
ми могли б використати тут деякі цифри
Зонко

1

Інший важливий момент полягає в тому, що (виправте мене, якщо я помиляюся тут) System.Collections.Generic.Dictionaryне можна використовувати в налаштуваннях програми ( Properties.Settings), тоді як System.Collections.Specialized.StringDictionaryце.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.