Ответ 1
Нет способа указать StringComparer
в точке, где вы пытаетесь получить значение. Если подумать, то "foo".GetHashCode()
и "FOO".GetHashCode()
совершенно разные, поэтому нет разумного способа реализовать регистронезависимое получение на чувствительной к регистру хеш-карте.
Однако вы можете создать словарь без учета регистра в первую очередь, используя: -
var comparer = StringComparer.OrdinalIgnoreCase;
var caseInsensitiveDictionary = new Dictionary<string, int>(comparer);
Или создайте новый нечувствительный к регистру словарь с содержимым существующего чувствительного к регистру словаря (если вы уверены, что нет столкновений с регистром): -
var oldDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
var newDictionary = new Dictionary<string, int>(oldDictionary, comparer);
Затем этот новый словарь использует реализацию GetHashCode()
в StringComparer.OrdinalIgnoreCase
, поэтому comparer.GetHashCode("foo")
и comparer.GetHashcode("FOO")
дают вам одинаковое значение.
В качестве альтернативы, если в словаре всего несколько элементов и/или вам нужно искать только один или два раза, вы можете рассматривать исходный словарь как IEnumerable<KeyValuePair<TKey, TValue>>
и просто выполнять итерацию по нему: -
var myKey = ...;
var myDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
var value = myDictionary.FirstOrDefault(x => String.Equals(x.Key, myKey, comparer)).Value;
Или, если хотите, без LINQ: -
var myKey = ...;
var myDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
int? value;
foreach (var element in myDictionary)
{
if (String.Equals(element.Key, myKey, comparer))
{
value = element.Value;
break;
}
}
Это экономит затраты на создание новой структуры данных, но взамен стоимость поиска составляет O (n) вместо O (1).