提问人:Enrico Massone 提问时间:5/12/2020 最后编辑:Enrico Massone 更新时间:5/12/2020 访问量:688
何时应使用 StringComparison.InvariantCulture 而不是 StringComparison.CurrentCulture 来测试字符串是否相等?
When should I use StringComparison.InvariantCulture instead of StringComparison.CurrentCulture to test string equality?
问:
根据我的理解(参见我的另一个问题),为了决定是否使用序号规则或文化规则来测试字符串相等性,必须考虑执行比较的语义。
如果必须将两个比较的字符串视为原始字符序列(换句话说,两个符号),则必须执行序号字符串比较。在服务器端代码中执行的大多数字符串比较都是这种情况。
示例:按用户名执行用户查找。在这种情况下,可用用户的用户名和搜索到的用户名只是符号,它们不是特定语言中的单词,因此在比较它们时无需考虑语言元素。在这种情况下,无论任何语言规则如何,都必须将由不同字符组成的两个符号视为不同符号。
如果必须将两个比较的字符串视为特定语言中的单词,则在比较过程中必须考虑文化规则。根据某种语言的语法规则,由不同字符组成的两个字符串完全有可能在某种语言中被视为同一个单词。
示例:这两个词在德语中具有相同的含义。因此,在比较代表德语单词的字符串的上下文中,必须考虑此语法规则,并且必须将这两个字符串视为相等(想想德国市场的应用程序,其中用户输入街道名称,并且必须将该街道搜索到数据库中,以获取街道所在的城市)。strasse
straße
street
目前为止,一切都好。
鉴于所有这些,在哪些情况下使用 .NET 固定区域性来实现字符串相等是有意义的?
关键是不变文化(与上面例子中提到的德国文化相反)是一种基于美国英语语言规则的假文化。 换句话说,没有一种人类语言的规则是基于 .NET 不变文化的,那么我为什么要使用这种虚构的文化来比较两个字符串呢?
我知道固定区域性通常用于格式化和解析机器对机器通信方案中使用的字符串(例如 Web API 公开的合约)。
我想了解何时调用 as versus (对于某些手动设置的线程文化,以便不依赖于机器操作系统配置)确实有意义。string.equals
StringComparison.InvariantCulture
StringComparison.CurrentCulture
答:
组合变音符号/非归一化字符串就是一个例子。请参阅此答案以获取代码的体面处理:https://stackoverflow.com/a/31361980/2701753
总之,对于(许多)“字母表”,同一字形(字母)有几种潜在的 Unicode(和 UCS-2)表示形式
例如:
Unicode Character “á” (U+00E1) [one unicode codepoint]
Unicode Character “a” (U+0061) [followed by] Unicode Character “◌́” (U+0301) [two unicode codepoints]
so:
á
á
相同的语言字符串(对于所有区域性,它们应该表示相同的字符),但不同的序号字符串(不同的字节)。
因此,不变相等比较[在这种情况下]就像在比较字符串之前对字符串进行规范化
查找 unicode 规范化/分解以获取更多信息。
还有其他有趣的情况,例如连字。从左到右,从右到左标记和....
所以,总而言之,一旦你有了“有趣”的字母表(几乎是纯 ascii 之外的任何东西),一旦你对字符串作为语言项目/字形流的任何类型的比较感兴趣,你可能确实想超越序数比较。
直接回答这个问题:如果你有一个多元文化的用户群,但仍然需要上述语言敏感性,你会选择哪种文化:
StringComparison.CurrentCulture
(对于某些手动设置的线程区域性,以便不依赖于计算机操作系统配置)
除了 InvariantCulture?
评论
(strasse == straße) == true
(strasse == straße) == false