【问题标题】:Which is generally best to use — StringComparison.OrdinalIgnoreCase or StringComparison.InvariantCultureIgnoreCase?通常最好使用哪个 - StringComparison.OrdinalIgnoreCase 或 StringComparison.InvariantCultureIgnoreCase?
【发布时间】:2023-03-27 21:57:02
【问题描述】:

我有一些这样的代码:

If key.Equals("search", StringComparison.OrdinalIgnoreCase) Then
    DoSomething()
End If

我不关心这个案子。我应该使用OrdinalIgnoreCaseInvariantCultureIgnoreCase 还是CurrentCultureIgnoreCase

【问题讨论】:

标签: .net vb.net localization


【解决方案1】:

这取决于你想要什么,尽管我会回避不变文化,除非你非常确定你永远不想将代码本地化为其他语言。请改用 CurrentCulture。

此外,OrdinalIgnoreCase 应该尊重数字,这可能是也可能不是您想要的。

【讨论】:

  • 曾经在混合语言环境中编写过 VB6 代码吗?您可以创建在具有法语语言环境的 PC 上编译的代码,但不会在具有英语语言环境的 PC 上编译,因为存储在表单资源中的任何数字都使用当前语言环境的格式。我认为您需要采取相反的方法:在使用当前文化时要非常小心。始终考虑当数据在不同文化之间移动时您的系统是否仍能正常工作。时区也是如此。
  • 我同意“视情况而定”的答案。虽然没有遵循“尊重数字”这一点?
【解决方案2】:

Newer .Net Docs now has a table to help you decide which is best to use in your situation.

来自 MSDN 的“New Recommendations for Using Strings in Microsoft .NET 2.0

总结:以前使用InvariantCulture 进行字符串比较、大小写和排序的代码所有者应该强烈考虑在Microsoft .NET 2.0 中使用一组新的String 重载。 具体而言,设计为与文化无关和语言无关的数据应开始使用新StringComparison 枚举的StringComparison.OrdinalStringComparison.OrdinalIgnoreCase 成员指定重载。这些强制执行类似于strcmp 的逐字节比较,不仅避免了基本符号字符串的语言解释错误,而且提供了更好的性能。

【讨论】:

  • 举一个他们不同的例子,考虑两个字符串"Straße""STRASSE"。当使用OrdinalIgnoreCase 时,Equals 返回false,而InvariantCultureIgnoreCase 表示它们是相等的。
【解决方案3】:

我想这取决于你的情况。由于序数比较实际上是在查看字符的数字 Unicode 值,因此当您按字母顺序排序时,它们不是最佳选择。但是,对于字符串比较,序数会快一点。

【讨论】:

    【解决方案4】:

    这一切都取决于

    比较 unicode 字符串很难:

    Unicode字符串的实现 文本中的搜索和比较 处理软件必须考虑到 考虑等价物的存在 码点。在没有这个 功能,用户搜索 特定的代码点序列将 肉眼找不到其他 具有不可区分的字形 不同,但规范等效, 代码点表示。

    见:http://en.wikipedia.org/wiki/Unicode_equivalence


    如果您尝试以不区分大小写的方式比较 2 个 unicode 字符串并希望它在任何地方都能正常工作,那么您将遇到一个不可能的问题。

    经典的例子是Turkish i,当它大写时变成 İ(注意点)

    默认情况下,.Net 框架通常将CurrentCulture 用于与字符串相关的函数,但.Equals 是一个非常重要的例外,它使用序数(逐字节)比较。

    根据设计,这会导致各种字符串函数的行为因计算机文化而异。


    尽管如此,有时我们想要一个“通用”、不区分大小写的比较。

    例如,您可能希望字符串比较的行为方式相同,无论您的应用程序安装在哪台计算机上。

    要实现这一点,我们有 3 个选项:

    1. 明确设置区域性并使用 unicode 等效规则执行不区分大小写的比较。
    2. 将区域性设置为不变区域性并使用 unicode 等效规则执行不区分大小写的比较。
    3. 使用OrdinalIgnoreCase,它将使用 InvariantCulture 将字符串大写,然后执行逐字节比较。

    Unicode 等价规则很复杂,这意味着使用方法 1) 或 2) 比 OrdinalIgnoreCase 更昂贵。 OrdinalIgnoreCase 不执行任何特殊的 unicode 规范化这一事实意味着,某些在计算机屏幕上以相同方式呈现的字符串,不会被视为相同。例如:"\u0061\u030a""\u00e5" 都呈现 å。但是在序数比较中会被认为是不同的。

    您选择哪一个很大程度上取决于您正在构建的应用程序。

    • 如果我正在编写一个仅供土耳其用户使用的业务线应用程序,我肯定会使用方法 1。
    • 如果我只需要一个简单的“假”不区分大小写的比较,例如数据库中的列名,通常是英文,我可能会使用方法 3。

    Microsoft 的set of recommendations 有明确的指导方针。但是,在解决这些问题之前了解 unicode 等价的概念非常重要。

    另外,请记住,OrdinalIgnoreCase 是野兽的very special kind,与字典方面的一些混合相比,这是挑选和选择一些序数。这可能会令人困惑。

    【讨论】:

    • 如果我正在构建一个仅由土耳其用户使用但我希望“ayakkabı”和“ayakkabi”相等的土耳其应用程序,有什么办法吗?当人们在手机上打字时,他们中的大多数人默认使用英文键盘,并不关心他们输入的是“ı”还是“i”。
    【解决方案5】:

    非常简单的答案是,除非您使用土耳其语,否则您不需要使用 InvariantCulture。

    查看以下链接:

    In C# what is the difference between ToUpper() and ToUpperInvariant()?

    【讨论】:

    • 这个答案可能很简单,但也是非常错误的。土耳其语“I”只是一个示例,还有更多可能的陷阱。
    • 是的,除了土耳其语还有阿塞拜疆语。但就是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2013-05-28
    相关资源
    最近更新 更多