我正在 OsiSoft“PI”系统的字典中缓存一些数据,并通过字符串键对其进行索引。这些按键来自不同系统中的用户输入,并且大小写混合。 OsiSoft 系统键不区分大小写,因此我也需要我的字典不区分大小写。但是,字典没有按预期工作。
字典定义如下:
Dictionary<string, PIPoint> PointsDictionary = new Dictionary<string, PIPoint>(StringComparer.CurrentCultureIgnoreCase);
它由派生自 IList 的 OsiSoft 结构返回的结构填充
PointsDictionary = RegisteredPoints.ToDictionary(x => x.Name, x => x);
当我尝试从字典返回 PIPoint 值时,它没有按预期工作。我想以小写、大写或混合大小写的形式传递 Key,并获得相同的值。
public PIPoint GetPoint(string tag)
{
//sfiy-1401a/c6
//SFIY-1401A/C6
Debug.WriteLine("sfiy-1401a/c6" + ": " + PointsDictionary.ContainsKey("sfiy-1401a/c6"));
Debug.WriteLine("SFIY-1401A/C6" + ": " + PointsDictionary.ContainsKey("SFIY-1401A/C6"));
Debug.WriteLine("Match?" + ": " + "SFIY-1401A/C6".Equals("sfiy-1401a/c6", StringComparison.CurrentCultureIgnoreCase));
if (tag == null || !PointsDictionary.ContainsKey(tag)) return null;
return PointsDictionary[tag];
}
运行上述代码时调试器的输出:
sfiy-1401a/c6: False
SFIY-1401A/C6: True
Match?: True
我是否从根本上误解了不区分大小写的字典的工作原理,或者我填充它的方式(转换 IList.ToDictionary())是否意味着它没有按预期工作?
最佳答案
字典定义为不区分大小写,但随后您用区分大小写的字典覆盖它。
// definition
Dictionary<string, PIPoint> PointsDictionary = new Dictionary<string, PIPoint>(StringComparer.CurrentCultureIgnoreCase);
// later *reassignment*
PointsDictionary = RegisteredPoints.ToDictionary(x => x.Name, x => x);
你看,你正在替换这个值!当您覆盖该值时,原始比较器将丢失。当您调用ToDictionary
时,您需要再次指定比较器。幸运的是有一个overload这需要一个关键比较器:
PointsDictionary = RegisteredPoints.ToDictionary(x => x.Name, x => x, StringComparer.CurrentCultureIgnoreCase);
注意还有 overloads的 ToDictionary
只采用键选择器(和比较器),因此您可以简化为:
PointsDictionary = RegisteredPoints.ToDictionary(x => x.Name, StringComparer.CurrentCultureIgnoreCase);
您甚至可以传递original Comparer
所以你不必准确记住它是什么类型:
PointsDictionary = RegisteredPoints.ToDictionary(x => x.Name, PointsDictionary.Comparer);
或者,您可以清除字典并重新添加所有项目,这将保留原始比较器:
PointsDictionary.Clear():
foreach(var p in RegisteredPoints)
PointsDictionary[p.Name] = p:
关于c# - 不区分大小写的字典未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62544104/