在 C# 中具有字符串键类型的不区分大小写字典
Posted
技术标签:
【中文标题】在 C# 中具有字符串键类型的不区分大小写字典【英文标题】:Case-INsensitive Dictionary with string key-type in C# 【发布时间】:2012-12-08 22:41:27 【问题描述】:如果我有Dictionary<String,...>
,是否可以使ContainsKey
之类的方法不区分大小写?
这似乎相关,但我没有正确理解它:c# Dictionary: making the Key case-insensitive through declarations
【问题讨论】:
Case insensitive access for generic dictionary的可能重复 这个问题是相关的,但与这个问题并不完全重复。那一个进入如何处理现有的字典。我从新代码开始,所以这里的答案更适合。 【参考方案1】:这似乎相关,但我没有正确理解:c# Dictionary: making the Key case-insensitive through declarations
确实有关系。解决方案是告诉字典实例不要使用标准的字符串比较方法(区分大小写),而是使用不区分大小写的方法。这是使用appropriate constructor:
var dict = new Dictionary<string, YourClass>(
StringComparer.InvariantCultureIgnoreCase);
构造函数需要一个IEqualityComparer
,它告诉字典如何比较键。
StringComparer.InvariantCultureIgnoreCase
为您提供IEqualityComparer
实例,它以不区分大小写的方式比较字符串。
【讨论】:
可能,StringComparison.OrdinalIgnoreCase 比较器比基于文化的比较快:***.com/questions/492799/… @ShridharRKulkarni 你基本上不能(有效地)。比较逻辑是内部字典数据结构的核心部分。为此,容器必须为其数据维护多个索引,而字典不会这样做。【参考方案2】:var myDic = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
myDic.Add("HeLlo", "hi");
if (myDic.ContainsKey("hello"))
Console.WriteLine(myDic["hello"]);
【讨论】:
【参考方案3】:很少有机会处理从第三方或外部 dll 提取的字典。使用 linq
YourDictionary.Any(i => i.KeyName.ToLower().Contains("yourstring")))
【讨论】:
这很好用。不过需要注意的是,如果您将Any
更改为SingleOrDefault
,如果null
不存在,您将不会得到它,相反,您将获得一个键值对,键和值都设置为null
!跨度>
Contains
似乎是您当时正在做的事情的一个非常具体的用例。作为一个更通用的有用答案,我认为Equals
更好。同样的,与其用ToLower()
复制一个字符串,不如使用StringComparison.xxxCase
。
我很想对此投反对票。请注意,如果您是字典的所有者,那么这肯定不是这样做的方法。如果您不知道字典是如何实例化的,请仅使用此方法。即使这样,对于字符串的精确匹配(不仅仅是部分匹配),使用dict.Keys.Contains("bla", appropriate comparer)
LINQ 重载以方便使用。【参考方案4】:
如果您无法控制实例的创建,假设您的对象已从 json 等中删除,您可以创建一个继承自字典类的包装类。
public class CaseInSensitiveDictionary<TValue> : Dictionary<string, TValue>
public CaseInSensitiveDictionary() : base(StringComparer.OrdinalIgnoreCase)
【讨论】:
如何在保持 Dictionary我刚刚遇到了同样的麻烦,我需要在 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!");
【讨论】:
【参考方案6】:我知道这是一个较老的问题,但我遇到了同样的问题,即字典来自未在构造函数中实现忽略大小写 StringComparer 的第 3 方工具。从上面的 @Soviut 方法调整而来,但感觉这更干净,让您可以立即使用该值。
var lookup = source.FirstOrDefault(x => x.Key.Equals("...", StringComparison.OrdinalIgnoreCase));
if (lookup.Key != null)
【讨论】:
以上是关于在 C# 中具有字符串键类型的不区分大小写字典的主要内容,如果未能解决你的问题,请参考以下文章
re.sub() 的不区分大小写的正则表达式模式问题[重复]
nvarchar 类型的不区分大小写的主键,其中 ß != ss