我啥时候应该使用 StringComparison.InvariantCulture 而不是 StringComparison.CurrentCulture 来测试字符串是不是相等?

Posted

技术标签:

【中文标题】我啥时候应该使用 StringComparison.InvariantCulture 而不是 StringComparison.CurrentCulture 来测试字符串是不是相等?【英文标题】:When should I use StringComparison.InvariantCulture instead of StringComparison.CurrentCulture to test string equality?我什么时候应该使用 StringComparison.InvariantCulture 而不是 StringComparison.CurrentCulture 来测试字符串是否相等? 【发布时间】:2020-08-27 14:29:21 【问题描述】:

根据我的理解(见my other question),为了决定是否使用序数或文化规则来测试字符串相等性,必须考虑执行比较的语义

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

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

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

示例:strassestraße 这两个词在德语中与street 的含义相同。 因此,在比较表示德语单词的字符串时,必须考虑到这个语法规则,并且这两个字符串必须被视为相等(想想德国市场的应用程序,其中用户输入一条街道的名称和这条街道必须在数据库中搜索,才能得到街道所在的城市)。

到目前为止,一切都很好。

考虑到所有这些,在哪些情况下使用 .NET invariantculture 字符串 equality 有意义?

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

我知道不变文化通常用于格式化和解析机器对机器通信场景中使用的字符串(例如 Web API 公开的合约)。

我想了解当使用StringComparison.InvariantCulture 而不是StringComparison.CurrentCulture 调用string.equals 时(对于某些手动设置的线程文化,为了不依赖于机器操作系统配置)真的很有意义。

【问题讨论】:

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

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

【讨论】:

当然你可能需要自己动手,? = A??各种空格是否匹配[有很多] 简而言之,当字符串比较中需要语言敏感性时,必须使用不变的文化,但不可能确定特定的语言,因为不可能假设所有用户都有相同的语言。因此,当存在歧义时,使用文化是一种常规选择。

以上是关于我啥时候应该使用 StringComparison.InvariantCulture 而不是 StringComparison.CurrentCulture 来测试字符串是不是相等?的主要内容,如果未能解决你的问题,请参考以下文章

我啥时候应该使用 QThread::HighestPriority

Firebase:我啥时候应该使用 refreshToken?

我啥时候应该使用助手? [关闭]

我啥时候应该使用“while 循环”?

我啥时候应该在 C 中使用 malloc,啥时候不应该?

我啥时候应该在 C 中使用 malloc,啥时候不应该?