C#字符串比较:CurrentCultureIgnoreCase和InvariantCultureIgnoreCase之间的区别

42
当在C#中进行字符串比较时,使用 == 和 Equals() 的区别是什么?
string test = "testvalue";
test.Equals("TESTVALUE", StringComparison.CurrentCultureIgnoreCase);

并且

string test = "testvalue";
test.Equals("TESTVALUE", StringComparison.InvariantCultureIgnoreCase);

...而且,无论如何都要包含那个额外的参数吗?

2个回答

39

其他帖子给出了很好的建议,但我认为展示一个明显会有区别的例子可能会更好:

using System;
using System.Globalization;
using System.Threading;

class Test
{
    static void Main()
    {
        CultureInfo turkish = CultureInfo.CreateSpecificCulture("tr");
        Thread.CurrentThread.CurrentCulture = turkish;                

        // In Turkey, "i" does odd things
        string lower = "i";
        string upper = "I";
        
        // Prints False
        Console.WriteLine(lower.Equals(upper, 
            StringComparison.CurrentCultureIgnoreCase));
        // Prints True
        Console.WriteLine(lower.Equals(upper, 
            StringComparison.InvariantCultureIgnoreCase));
    }
}

(毫无疑问,还有许多其他情况 - 这只是我想到的第一个情况。)


8
是的,土耳其文中的字母i是一个特殊的例子。他们有一个没有点的小写“ı”,以及一个大写的“I”,还有一个小写的“i”和一个大写的“İ”。这被认为是文化差异的典型案例。 - configurator
3
关于土耳其语作为"规范性案例"的本质,更多信息请参见:http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html - JeffH
1
我在越南遇到了同样的事情:String.Compare("logid", "logId", StringComparison.CurrentCultureIgnoreCase) == 1。但是,String.Compare("id", "Id", StringComparison.CurrentCultureIgnoreCase) == 0 :O - Nhat Hong Ly
@JonSkeet的一个建议是稍微改进一下这个答案,即在答案中包含代码的输出(即False,然后是True)。 - LeopardSkinPillBoxHat

29

Microsoft提供了一些合理的指导,来帮助确定何时使用 InvariantCulture 属性:

MSDN: CultureInfo.InvariantCulture Property

... 应仅在需要与文化无关的结果的进程中使用不变的区域性,例如格式化和解析持久到文件的数据。否则,它会产生可能在语言上不正确或文化不适当的结果。

安全注意事项

如果一个基于字符串比较或大小写更改的安全决策将被做出,你的应用程序应该使用忽略大小写的序号比较,而不是使用InvariantCulture。[...]

字符串操作

如果您的应用程序需要执行一个与区域性有关的字符串操作,但不受CurrentCulture值的影响,则应使用接受CultureInfo参数的方法。[...]

持久化数据

InvariantCulture属性对于存储不直接显示给用户的数据非常有用。以文化无关的格式存储数据可以保证已知的格式不会发生变化。当来自不同文化的用户访问数据时,可以根据特定用户适当地进行格式化。[...]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接