我有一个使用托管dll的应用程序。其中一个dll返回一个泛型字典:
Dictionary<string, int> MyDictionary;
字典包含大小写键。
另一方面,我得到一个潜在的键(字符串)列表,但我不能保证的情况。我正在尝试使用键来获取字典中的值。但当然,以下将失败,因为我有一个情况不匹配:
bool Success = MyDictionary.TryGetValue( MyIndex, out TheValue );
我希望TryGetValue会像MSDN文档中提到的那样有一个忽略大小写标志,但这似乎对通用字典无效。
有没有办法得到忽略键大小写的字典的值?
是否有比使用正确的StringComparer创建字典的新副本更好的解决方法?OrdinalIgnoreCase参数?
没有办法在你试图获取一个值的时候指定一个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上的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)。