难道字符串比较确实有所不同基于文化当字符串保证不会发生变化?(Could string compar

2019-06-25 08:06发布

我是从一个配置文件读取加密凭据/连接字符串。 ReSharper的告诉我,“String.IndexOf(串)具有文化特性在这里”在这条线:

if (line.Contains("host=")) {
    _host = line.Substring(line.IndexOf(
        "host=") + "host=".Length, line.Length - "host=".Length);

......,因此希望将其改为:

if (line.Contains("host=")) {
    _host = line.Substring(line.IndexOf("host=", System.StringComparison.Ordinal) + "host=".Length, line.Length -   "host=".Length);

我读的价值永远是“主机=”无论在哪里,应用程序可以部署。 难道真的懂事添加此“System.StringComparison.Ordinal”位?

更重要的是,它可以伤害任何东西(用它)?

Answer 1:

绝对。 每MSDN( http://msdn.microsoft.com/en-us/library/d93tkzah.aspx )

此方法执行字(区分大小写和文化敏感 )使用当前区域性搜索。

所以,如果你(在控制面板中通过区域和语言设置)不同文化下运行它,你可能会得到不同的结果。

在这种特殊情况下,你可能不会有问题,但引发i的搜索字符串,并在土耳其运行它,它可能会毁了你的一天。

请参阅MSDN: http://msdn.microsoft.com/en-us/library/ms973919.aspx

这些新的建议和API存在以减轻约默认字符串的API的行为误导的假设。 错误出现在那里的非语言字符串数据语言解释的典型的例子就是“土耳其-I”的问题。

对于几乎所有的拉丁字母,包括美国英语,字符I(\ u0069)是字符I(\ u0049)的小写版本。 该套规则很快成为这种文化的人编程的缺省设置。 然而,在土耳其(“TR-TR”),存在一个资本。“我点,”字符(\ u0130),这是我的资本版本。 类似地,在土耳其语中,有一个小写的“i没有一个点,”或(\ u0131),其以大写I.此行为在阿泽培养物(“AZ”)时也是如此。

因此,假设通常由约大写I或lowercasing我是不是所有的文化中有效。 如果用于字符串比较例程默认重载,他们会受到文化之间的差异。 对于非语言数据,如在下面的例子中,这可能会产生不期望的结果:

    Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US")
Console.WriteLine("Culture = {0}",
   Thread.CurrentThread.CurrentCulture.DisplayName);
Console.WriteLine("(file == FILE) = {0}", 
   (String.Compare("file", "FILE", true) == 0));

Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");
Console.WriteLine("Culture = {0}",
   Thread.CurrentThread.CurrentCulture.DisplayName);
Console.WriteLine("(file == FILE) = {0}", 
   (String.Compare("file", "FILE", true) == 0));

因为我比较的差异,比较的结果改变时,线程的区域性变化。 这是输出:

Culture = English (United States)
(file == FILE) = True
Culture = Turkish (Turkey)
(file == FILE) = False

这里是没有情况下的实例:

var s1 = "é"; //é as one character (ALT+0233)
var s2 = "é"; //'e', plus combining acute accent U+301 (two characters)

Console.WriteLine(s1.IndexOf(s2, StringComparison.Ordinal)); //-1
Console.WriteLine(s1.IndexOf(s2, StringComparison.InvariantCulture)); //0
Console.WriteLine(s1.IndexOf(s2, StringComparison.CurrentCulture)); //0


Answer 2:

CA1309:UseOrdinalStringComparison

它不会到不使用它,而是“ 由参数明确设置到无论是StringComparison.Ordinal或StringComparison.OrdinalIgnoreCase,你的代码屡屡斩获速度,提高正确性,并变得更加可靠。”


究竟是什么序号,以及它为什么重要,以你的情况?

使用序号排序规则的操作进行基于数字值(Unicode代码点)的每个字符的字符串中的比较。 一个序号比较快,但文化不敏感。 当您使用序号排序规则与Unicode字符(U +),字符串,如果XXXX的值在数值上比YYYY少U + XXXX字符串U + YYYY之前谈到开头的字符串进行排序。

而且,正如你说...你正在阅读的字符串值不是文化敏感,所以是有意义的使用序号比较,而不是一个字比较。 只要记住,有序的意思是“这不是文化敏感”。



Answer 3:

为了回答您的具体问题:没有,但一个静态分析工具是不是要能够认识到你的输入值永远不会有它特定的语言环境的信息。



文章来源: Could string comparisons really differ based on culture when the string is guaranteed not to change?