У меня есть приложение, которое использует управляемые DLL. Один из этих dll возвращает общий словарь:
Dictionary<string, int> MyDictionary;
Словарь содержит ключи с прописными и строчными буквами.
С другой стороны, я получаю список потенциальных ключей (строка), однако я не могу гарантировать случай. Я пытаюсь получить значение в словаре, используя ключи. Но, конечно, следующее не получится, так как у меня несоответствие регистра:
bool Success = MyDictionary.TryGetValue( MyIndex, out TheValue );
Я надеялся, что у TryGetValue будет флаг игнорирования, как упомянуто в документе MSDN , но, похоже, это недопустимо для универсальных словарей.
Есть ли способ получить значение этого словаря, игнорируя регистр ключей? Есть ли лучший обходной путь, чем создание новой копии словаря с соответствующим параметром StringComparer.OrdinalIgnoreCase ?
c#
generics
dictionary
TocToc
источник
источник
Ответы:
Там нет никакого способа указать
StringComparer
в точке, где вы пытаетесь получить значение. Если вы думаете об этом,"foo".GetHashCode()
и"FOO".GetHashCode()
все совершенно по-другому, то нет никакого разумного способа реализовать регистронезависимое попадание на чувствительную к регистру хэш-карту.Однако вы можете создать словарь без учета регистра в первую очередь, используя: -
Или создайте новый нечувствительный к регистру словарь с содержимым существующего чувствительного к регистру словаря (если вы уверены, что нет коллизий):
Этот новый словарь затем использует
GetHashCode()
реализациюStringComparer.OrdinalIgnoreCase
такcomparer.GetHashCode("foo")
иcomparer.GetHashcode("FOO")
дает вам то же значение.В качестве альтернативы, если в словаре всего несколько элементов и / или вам нужно искать только один или два раза, вы можете рассматривать исходный словарь как
IEnumerable<KeyValuePair<TKey, TValue>>
и просто перебирать его: -Или, если вы предпочитаете, без LINQ: -
Это экономит затраты на создание новой структуры данных, но взамен стоимость поиска составляет O (n) вместо O (1).
источник
default(KeyValuePair<T, U>)
неnull
- этоKeyValuePair
гдеKey=default(T)
иValue=default(U)
. Таким образом, вы не можете использовать?.
оператор в примере LINQ; вам нужно взятьFirstOrDefault()
и затем (для этого конкретного случая) проверить, еслиKey == null
.Для вас, LINQers, которые никогда не используют обычный словарь конструктора:
источник
Это не очень элегантно, но в случае, если вы не можете изменить создание словаря, и все, что вам нужно, это грязный хак, как насчет этого:
источник
ToUpperInvariant
вместоToLower
. msdn.microsoft.com/en-us/library/dd465121%28v=vs.110%29.aspxvar item = MyDictionary.FirstOrDefault(x => x.Key.ToUpperInvariant() == keyValueToCheck.ToUpperInvariant());
dict.Keys.Contains("bla", appropriate comparer)
? Кроме того, вы не получите null для FirstOrDefault, поскольку пара ключей в C # является структурой.