通用字典的大小写不敏感访问

我有一个使用托pipedll的应用程序。 其中一个DLL返回一个通用字典:

Dictionary<string, int> MyDictionary; 

字典包含大写和小写的键。

另一方面,我得到一个潜在的钥匙(string)列表,但我不能保证的情况下。 我正在尝试使用键获取字典中的值。 但是,当然以下将失败,因为我有一个案件不匹配:

 bool Success = MyDictionary.TryGetValue( MyIndex, out TheValue ); 

我希望TryGetValue将有一个像MSDN文档中提到的忽略大小写标志,但它似乎对通用字典无效。

有没有办法让字典的价值忽略关键的情况? 有没有比使用正确的StringComparer.OrdinalIgnoreCase参数创build字典的新副本更好的解决方法?

在尝试获取值时,无法指定StringComparer 。 如果你仔细想想, "foo".GetHashCode()"FOO".GetHashCode()是完全不同的,所以没有合理的方法来实现区分大小写的区分大小写的散列映射。

但是,您可以使用以下命令首先创build不区分大小写的字典:

 var comparer = StringComparer.OrdinalIgnoreCase; var caseInsensitiveDictionary = new Dictionary<string, int>(comparer); 

或者用现有区分大小写的字典的内容创build一个不区分大小写的新字典(如果您确定不存在大小写冲突): –

 var oldDictionary = ...; var comparer = StringComparer.OrdinalIgnoreCase; var newDictionary = new Dictionary<string, int>(oldDictionary, comparer); 

这个字典然后使用StringComparer.OrdinalIgnoreCase上的GetHashCode()实现, comparer.GetHashCode("foo")comparer.GetHashcode("FOO")给你相同的值。

或者,如果字典中只有less量元素,并且/或者只需要查找一次或两次,则可以将原始字典视为IEnumerable<KeyValuePair<K,T>>然后迭代它:

 var myKey = ...; var myDictionary = ...; var comparer = StringComparer.IgnoreOrdinalCase; var value = myDictionary.FirstOrDefault(x => String.Equals(x.Key, myKey, comparer))?.Value; 

或者,如果你喜欢,没有LINQ: –

 var myKey = ...; var myDictionary = ...; var comparer = StringComparer.IgnoreOrdinalCase; int? value; foreach (var element in myDictionary) { if (String.Equals(element.Key, myKey, comparer)) { value = element.Value; break; } } 

这为您节省了创build新数据结构的成本,但是作为回报,查找的代价是O(n)而不是O(1)。

它不是很优雅,但如果你不能改变字典的创build,而你所需要的只是一个肮脏的黑客,那么这个怎么样:

 var item = MyDictionary.Where(x => x.Key.ToLower() == MyIndex.ToLower()).FirstOrDefault(); if (item != null) { TheValue = item.Value; } 

为了你linqers在那里,从来没有使用常规的字典构造函数。

 myCollection.ToDictionary(x => x.PartNumber, x => x.PartDescription, StringComparer.OrdinalIgnoreCase)