Может ли сравнение строк действительно отличаться в зависимости от культуры, когда строка гарантированно не изменится?
Я читаю зашифрованные учетные данные / строки подключения из файла конфигурации. Решарпер говорит мне: "Струна.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= " независимо от того, где может быть развернуто приложение. Действительно ли разумно добавить эту "систему".Сравнение строк.Порядковый номер " бит?
что еще более важно, может ли это повредить что-нибудь (использовать это)?
3 ответа:
абсолютно. На MSDN (http://msdn.microsoft.com/en-us/library/d93tkzah.aspx),
этот метод выполняет слово (с учетом регистра и культуры) поиск с использованием текущего языка и региональных параметров.
таким образом, вы можете получить разные результаты, если вы запустите его под другой культурой (через региональные и языковые настройки в Панели Управления).
в этом конкретном случае у вас, вероятно, не будет проблем, но бросьте Ан
i
в строке поиска и запустить его в Турции, и это, вероятно, испортит ваш день.см. MSDN:http://msdn.microsoft.com/en-us/library/ms973919.aspx
эти новые рекомендации и API существуют для устранения ошибочных предположений о поведении строковых API по умолчанию. Каноническое пример ошибок, возникающих там, где неязыковые строковые данные лингвистически интерпретируется проблема "турецкого я".
для почти все латинские алфавиты, включая американский английский, характер i (\u0069) - это строчная версия символа I (\u0049). Этот правило оболочки быстро становится значением по умолчанию для кого-то, кто программирует такая культура. Однако в турецком языке ("tr-TR") существует столица "я с точкой", символ (\u0130), который является заглавной версией i. точно так же в турецком языке есть строчная буква "i без точки", или (\u0131), который с большой буквы I. Такое поведение происходит в азербайджанском языке культура ("аз") тоже.
поэтому обычно делаются предположения о капитализации i или строчные буквы I не являются допустимыми для всех культур. Если по умолчанию перегрузки используется для сравнения строк, они будут с учетом различий между культурами. Для неязыковых данных, как в в следующем примере это может привести к нежелательным результатам:
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));
из-за разницы сравнения I, результаты сравнения изменение при изменении языка и региональных параметров потока. Это вывод:
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.Порядковый номер или сравнение строк.OrdinalIgnoreCase, код часто набирает скорость, увеличивает правильность и становится более надежным.".
Что такое порядковый номер, и почему это имеет значение для вашего случая?
операция, использующая порядковую сортировку правила выполняет сравнение на основе о числовом значении (кодовая точка Юникода) каждого символа в строке. Порядковое сравнение выполняется быстро, но без учета культуры. Когда вы используете правила сортировки строк, начинающихся с символа Юникода (U+), строка U + xxxx предшествует строке U+yyyy, если значение xxxx численно меньше, чем yyyy.
и, как вы заявили... строковое значение, которое Вы читаете, не зависит от культуры, поэтому имеет смысл использовать Порядковое сравнение, в отличие от сравнения, слова. Просто помните, что порядковый номер означает "это не чувствительно к культуре".