泛型字典的不区分大小写访问

我有一个使用托管dll的应用程序。其中一个dll返回一个泛型字典:

Dictionary<string, int> MyDictionary;

字典包含大小写键。

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

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

我希望TryGetValue会有忽略大小写标志,就像MSDN文档中提到的那样,但这似乎对泛型字典无效。

是否有一种方法来获得忽略键大小写的字典的值? 是否有比使用正确的StringComparer。OrdinalIgnoreCase形参创建字典的新副本更好的解决方法?< / p >
167003 次浏览

在你试图获取一个值时,没有办法指定StringComparer。如果你仔细想想,"foo".GetHashCode()"FOO".GetHashCode()是完全不同的,所以没有合理的方法可以在区分大小写的哈希映射上实现不区分大小写的get。

然而,你可以首先使用:-创建一个不区分大小写的字典

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);

这个新字典然后使用StringComparer.OrdinalIgnoreCase上的GetHashCode()实现,因此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)。

它不是很优雅,但如果你不能改变字典的创建,你所需要的只是一个肮脏的hack,怎么样:

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

对于那些从未使用常规字典构造函数的linqer

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

还有更简单的方法:

using System;
using System.Collections.Generic;
....
var caseInsensitiveDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);