何时应使用 StringComparison.InvariantCulture 而不是 StringComparison.CurrentCulture 来测试字符串是否相等?

When should I use StringComparison.InvariantCulture instead of StringComparison.CurrentCulture to test string equality?

提问人:Enrico Massone 提问时间:5/12/2020 最后编辑:Enrico Massone 更新时间:5/12/2020 访问量:688

问:

根据我的理解(参见我的另一个问题),为了决定是否使用序号规则或文化规则来测试字符串相等性,必须考虑执行比较的语义

如果必须将两个比较的字符串视为原始字符序列(换句话说,两个符号),则必须执行序号字符串比较。在服务器端代码中执行的大多数字符串比较都是这种情况。

示例:按用户名执行用户查找。在这种情况下,可用用户的用户名和搜索到的用户名只是符号,它们不是特定语言中的单词,因此在比较它们时无需考虑语言元素。在这种情况下,无论任何语言规则如何,都必须将由不同字符组成的两个符号视为不同符号。

如果必须将两个比较的字符串视为特定语言中的单词,则在比较过程中必须考虑文化规则。根据某种语言的语法规则,由不同字符组成的两个字符串完全有可能在某种语言中被视为同一个单词

示例:这两个词在德语中具有相同的含义。因此,在比较代表德语单词的字符串的上下文中,必须考虑此语法规则,并且必须将这两个字符串视为相等(想想德国市场的应用程序,其中用户输入街道名称,并且必须将该街道搜索到数据库中,以获取街道所在的城市)。strassestraßestreet

目前为止,一切都好。

鉴于所有这些,在哪些情况下使用 .NET 固定区域性来实现字符串相等是有意义的?

关键是不变文化(与上面例子中提到的德国文化相反)是一种基于美国英语语言规则的文化。 换句话说,没有一种人类语言的规则是基于 .NET 不变文化的,那么我为什么要使用这种虚构的文化来比较两个字符串呢?

我知道固定区域性通常用于格式化和解析机器对机器通信方案中使用的字符串(例如 Web API 公开的合约)。

我想了解何时调用 as versus (对于某些手动设置的线程文化,以便不依赖于机器操作系统配置)确实有意义。string.equalsStringComparison.InvariantCultureStringComparison.CurrentCulture

C# .NET 字符串 CultureInfo InvariantCulture

评论

0赞 Austin T French 5/12/2020
strasse 和 straße 是否相等,是域的函数,而不是 .net 甚至 C#。在某些情况下,您要进行评估,有时.您的业务逻辑应该决定如何比较字符串...(strasse == straße) == true(strasse == straße) == false
0赞 Enrico Massone 5/12/2020
@AustinTFrench完全同意你的看法。这是在序号字符串比较和区域性感知字符串比较之间进行选择时使用的基本原理。我的问题是,使用固定区域性,而不是特定区域性(en-gb、fr-fr、ecc...)对于区域性感知字符串比较是否真的有意义。
1赞 Hans Passant 5/12/2020
InvariantCulture 是对“如果每个人都以不同的方式做,那么标准是什么”这个问题的简单答案。例如,如果您有一个配置文件,该文件指定了用户可以更改的浮点数的默认值,您可能会喜欢它。由于在部署该文件时,您永远无法正确猜测该用户是否使用逗号或小数点,因此您必须选择一个标准。方便。确保用户在更改它时对它是显而易见的,即使你不需要它,也要使用'.。
0赞 Flydog57 5/12/2020
请考虑以下情况:您有一个字段,该字段表示程序已知但未在 UI 中公开的内容的名称。名称将是不变的,而不是您将本地化的名称

答:

4赞 tolanj 5/12/2020 #1

组合变音符号/非归一化字符串就是一个例子。请参阅此答案以获取代码的体面处理: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?

评论

0赞 tolanj 5/12/2020
当然,您可能需要自己滚动,A = A??各种空格是否匹配[有很多]
0赞 Enrico Massone 5/12/2020
因此,简而言之,每当在字符串比较中需要语言敏感性时,就必须使用固定区域性,但无法确定特定语言,因为不可能假设所有用户都具有相同的语言。因此,当存在歧义时,使用文化是一种常规选择。