通常最好使用哪种-StringComparison.OrdinalIgnoreCase或StringComparison.InvariantCultureIgnoreCase?


161

我有一些这样的代码:

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

我不在乎这个案子。我应该使用OrdinalIgnoreCaseInvariantCultureIgnoreCaseCurrentCultureIgnoreCase


2
检查它对于此线程确实有用。我建议使用ordianlignorecase进行比较。blogs.msdn.com/b/noahc/archive/2007/06/29/...
UmaMaheswaran


总体而言,这很大程度上取决于您要比较的东西。具体来说,如果是与文化相关的用户输入或内部内容。您不希望PC的文化搞砸内部代码字符串进行比较。
Nyerguds

Answers:


179

较新的.Net Docs现在具有一个表格,可帮助您决定哪种方式最适合您的情况。

摘自MSDN的“ 在Microsoft .NET 2.0中使用字符串的新建议

摘要:以前InvariantCulture用于字符串比较,大小写和排序的代码所有者应强烈考虑String在Microsoft .NET 2.0中使用一组新的重载。具体来说,被设计为与文化无关且在语言上不相关的数据应开始使用新枚举的StringComparison.OrdinalStringComparison.OrdinalIgnoreCase成员指定重载StringComparison。它们强制进行逐字节比较,strcmp这不仅避免了实质上是符号字符串的语言解释带来的错误,而且还提供了更好的性能。


126
为了举例说明它们之间的区别,请考虑两个字符串"Straße""STRASSE"。当使用OrdinalIgnoreCaseEquals收益false,而InvariantCultureIgnoreCase说他们是平等的。
Jeppe Stig Nielsen


63

一切取决于

比较unicode字符串很难:

文本处理软件中Unicode字符串搜索和比较的实现必须考虑到等效代码点的存在。在没有此功能的情况下,搜索特定代码点序列的用户将无法找到具有不同但规范上等效的代码点表示形式的其他视觉上无法区分的字形。

请参阅:http : //en.wikipedia.org/wiki/Unicode_equivalence


如果你想在不区分大小写的方式来比较2个unicode字符串,并希望它的工作无处不在,你有一个不可能的问题。

典型的例子是土耳其语i,当大写时变成İ(注意点)

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

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


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

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

为此,我们有3种选择:

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

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

选择哪种取决于您正在构建的应用程序。

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

Microsoft有其明确建议的一组建议。但是,在解决这些问题之前理解unicode等效的概念确实很重要。

另外,请记住,OrdinalIgnoreCase是一种非常特殊的野兽,即与字典混合中的某些杂项相比,可以选择并选择一些序数。这可能会造成混淆。


4

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


1

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

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


1
您是否曾经在混合语言环境中编写过VB6代码?您可以创建可在具有法语语言环境的PC上编译的代码,但不会在具有英语语言环境的PC上编译的代码,因为存储在表单资源中的任何数字均使用当前语言环境的格式。我认为您需要采取相反的方法:使用当前的文化时要非常小心。当数据在不同文化之间移动时,请始终考虑您的系统是否仍然可以工作。时区也一样。
Wim Coenen

我同意“视情况而定”的答案。虽然没有遵循“尊重数字”位?
山姆·萨弗隆

-1

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

请参阅以下链接:

在C#中,ToUpper()和ToUpperInvariant()有什么区别?


5
这个答案可能很简单,但这也是非常错误的。土耳其语“ I”仅是一个例子,还有更多可能的陷阱。
Ohad Schneider 2014年

还有哪些陷阱?我只知道土耳其问题案例。
HelloWorld

是的,除了土耳其语外还有Azeri。就是这样。
Jim Balter
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.