当string保证不会改变时,string比较是否真的可以根据文化而不同?
我从configuration文件读取encryption的凭据/连接string。 Resharper告诉我,“String.IndexOf(string)在这里是文化特定的”:
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);
我正在阅读的值将永远是“host =”,无论应用程序可能部署在哪里。 添加这个“System.StringComparison.Ordinal”位是否真的明智?
更重要的是,它可以伤害任何东西(使用它)?
绝对。 每个MSDN( http://msdn.microsoft.com/en-us/library/d93tkzah.aspx ),
该方法使用当前文化执行一个词(区分大小写且区分文化)。
因此,如果您在不同的文化下运行它(通过控制面板中的区域和语言设置),您可能会得到不同的结果。
在这个特殊情况下,你可能不会遇到任何问题,但是在searchstring中inputi
并在土耳其运行,这可能会毁了你的一天。
请参阅MSDN: http : //msdn.microsoft.com/en-us/library/ms973919.aspx
这些新的build议和API存在以减轻对默认stringAPI行为的错误假设。 非语言string数据在语言上被解释的错误出现的典型例子是“土耳其-I”问题。
对于几乎所有的拉丁字母,包括美国英语,字符i(\ u0069)是字符I(\ u0049)的小写版本。 这种shell规则很快成为这种文化中编程人员的默认设置。 然而,在土耳其语(“tr-TR”)中,存在一个首字母“I with a dot”的字符(\ u0130),它是i的首字母版本。 同样,在土耳其语中,有一个小写字母“i without a dot”或(\ u0131),这个字母大写I.这种行为也发生在阿塞拜疆文化(“az”)中。
因此,通常对我进行资本化或对我进行降低的假设在所有文化中都是无效的。 如果使用string比较例程的默认重载,它们将会受到不同文化之间的差异。 对于非语言数据,如下例所示,这可能会产生不希望的结果:
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
CA1309:UseOrdinalStringComparison
不要使用它,但是“ 通过显式地将参数设置为StringComparison.Ordinal或者StringComparison.OrdinalIgnoreCase,你的代码通常会提高速度,增加正确性,并且变得更可靠 ”。
Ordinal到底是什么,为什么你的情况很重要?
使用序号sorting规则的操作将根据string中每个Char的数值(Unicode码点)执行比较。 序数比较很快,但是对文化不敏感。 当使用序号sorting规则对以Unicode字符(U +)开头的string进行sorting时,如果xxxx的值在数字上小于yyyy,则stringU + xxxx位于stringU + yyyy之前。
而且,正如你所说…你阅读的string值不是文化敏感的,所以使用序数比较而不是字比较是有意义的。 请记住,序数意味着“这不是文化敏感”。
回答您的具体问题:不,但是静态分析工具无法实现您的input值永远不会在其中包含特定于语言环境的信息。