Якщо у мене Dictionary<String,...>
є, чи можливо зробити такі методи, як ContainsKey
нечутливі до регістру?
Це здавалося пов’язаним, але я не зрозумів це належним чином: c # Словник: створення Ключового випадку нечутливого через декларації
Якщо у мене Dictionary<String,...>
є, чи можливо зробити такі методи, як ContainsKey
нечутливі до регістру?
Це здавалося пов’язаним, але я не зрозумів це належним чином: c # Словник: створення Ключового випадку нечутливого через декларації
Відповіді:
Це здавалося пов’язаним, але я не зрозумів це належним чином: c # Словник: створення Ключового випадку нечутливого через декларації
Це справді пов’язано. Рішення полягає в тому, щоб сказати екземпляру словника не використовувати стандартний метод порівняння рядків (який враховує регістри), а скористатися нечутливим до регістру. Це робиться за допомогою відповідного конструктора :
var dict = new Dictionary<string, YourClass>(
StringComparer.InvariantCultureIgnoreCase);
Конструктор очікує, IEqualityComparer
що говорить словнику, як порівнювати ключі.
StringComparer.InvariantCultureIgnoreCase
дає вам IEqualityComparer
екземпляр, який порівнює рядки в нечутливому до регістру манері.
var myDic = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
myDic.Add("HeLlo", "hi");
if (myDic.ContainsKey("hello"))
Console.WriteLine(myDic["hello"]);
Мало шансів, коли ваша справа зі словником, який витягується з сторонніх або зовнішніх dll. Використання linq
YourDictionary.Any(i => i.KeyName.ToLower().Contains("yourstring")))
Any
до SingleOrDefault
вам не отримаєте null
назад , якщо він не існує, натомість ви отримаєте KeyValuePair як з ключем і встановлює null
!
Contains
Здається, це дуже специфічний випадок, коли ви працювали в той час. Як більш загальну корисну відповідь, я вважаю, що Equals
це краще. І на цій самій ноті замість того, щоб дублювати рядок з ToLower()
, було б ще краще використовувати StringComparison.xxxCase
.
dict.Keys.Contains("bla", appropriate comparer)
LINQ перевантаження для зручності використання.
Я просто зіткнувся з такою ж проблемою, коли мені потрібен словник caseINsensitive в контролері ASP.NET Core.
Я написав метод розширення, який робить трюк. Можливо, це може бути корисним і для інших ...
public static IDictionary<string, TValue> ConvertToCaseInSensitive<TValue>(this IDictionary<string, TValue> dictionary)
{
var resultDictionary = new Dictionary<string, TValue>(StringComparer.InvariantCultureIgnoreCase);
foreach (var (key, value) in dictionary)
{
resultDictionary.Add(key, value);
}
dictionary = resultDictionary;
return dictionary;
}
Щоб використовувати метод розширення:
myDictionary.ConvertToCaseInSensitive();
Потім отримайте значення зі словника за допомогою:
myDictionary.ContainsKey("TheKeyWhichIsNotCaseSensitiveAnymore!");
Якщо у вас немає контролю над створенням екземпляра, скажімо, ваш об’єкт дестерилізований з json тощо, ви можете створити клас обгортки, який успадковується від класу словника.
public class CaseInSensitiveDictionary<TValue> : Dictionary<string, TValue>
{
public CaseInSensitiveDictionary() : base(StringComparer.OrdinalIgnoreCase){}
}
StringComparer.InvariantCultureIgnoreCase
? Він робить те, що говорить ...