Словник c #: робимо ключ нечутливим до регістру за допомогою оголошень


74

У мене є Dictionary<string, object>словник. Раніше це було, Dictionary<Guid, object>але інші «ідентифікатори» почали діяти, і тепер ключі обробляються як рядки.

Проблема в тому, що Guidключі з моїх вихідних даних надходять як VarChar, тому зараз ключ "923D81A0-7B71-438d-8160-A524EA7EFA5E"не є таким самим, як "923d81a0-7b71-438d-8160-a524ea7efa5e"(не було проблемою при використанні посібників).

Що справді приємно (і солодко) у .NET framework, це те, що я можу зробити це:

Dictionary<string, CustomClass> _recordSet = new Dictionary<string, CustomClass>(
    StringComparer.InvariantCultureIgnoreCase);

І це чудово працює. Але як щодо вкладеного словника? Як наступне:

Dictionary<int, Dictionary<string, CustomClass>> _customRecordSet 
    = new  Dictionary<int, Dictionary<string, CustomClass>>();

Як я можу вказати порівняльник рядків у вкладеному словнику, як цей?


26
Лише підказка, можливо, вам доведеться переглянути використання StringComparer.InvariantCultureIgnoreCase. Цей порівняльник є повільним, оскільки він порівнює рядки за допомогою класів символів для подолання міжкультурних відмінностей. Це означає, що слово Straßeбуде трактуватися як рівне Strasseі навпаки. Я припускаю, що ви не хочете такої поведінки, і якщо продуктивність має вирішальне значення (якщо ви реалізуєте щось на зразок шару кешу над базою даних), то вам було б краще використовувати StringComparer.OrdinalIgnoreCase. Порядковий порівняльник - це найшвидший порівняльник рядків, який може запропонувати платформа .NET.
Івайло Славов

3
Можливий дублікат
безчутливого

2
Невже @ avs099? Ця публікація, на яку ви зв’язали, на рік молодша за цю. Ви навіть помітили?
AustinWBryan

3
@AustinWBryan: "Можливий дублікат" - це спосіб очищення - закрити подібні запитання та зберегти одне з найкращими відповідями. Дата не є важливою. Див. Чи повинен я голосувати за закриття дубліката запитання, хоча воно набагато новіше і містить новітні відповіді?
Michael Freidgeim

Відповіді:


80

Коли ви додаєте елемент до зовнішнього словника, ви, швидше за все, створите новий екземпляр вкладеного словника, додайте його в цей момент, використовуючи перевантажений конструктор, який приймає файл IEqualityComparer<TKey>.

_customRecordSet.Add(0, new Dictionary<string, CustomClass>(StringComparer.InvariantCultureIgnoreCase));


Оновлення 03.03.2017: Незвично, я десь читав (я думаю, у "Написанні високопродуктивного коду .NET"), що StringComparer.OrdinalIgnoreCaseє більш ефективним, коли просто хочеться ігнорувати регістр символів. Це, однак, є абсолютно необґрунтованим мною, тому YMMV.


8

Вам доведеться ініціалізувати вкладені словники, щоб використовувати їх. Просто використовуйте код, який ви мали вище, на той момент.

В основному, у вас повинен бути такий код:

public void insert(int int_key, string guid, CustomClass obj)
{
    if (_customRecordSet.ContainsKey(int_key)
         _customRecordSet[int_key][guid] = obj;
    else
    {
         _customRecordSet[int_key] = new Dictionary<string, CustomClass> 
                                     (StringComparer.InvariantCultureIgnoreCase);
         _customRecordSet[int_key][guid] = obj;
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.