Может ли сравнение строк действительно отличаться в зависимости от культуры, когда строка гарантированно не изменится?


Я читаю зашифрованные учетные данные / строки подключения из файла конфигурации. Решарпер говорит мне: "Струна.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 51

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.

и, как вы заявили... строковое значение, которое Вы читаете, не зависит от культуры, поэтому имеет смысл использовать Порядковое сравнение, в отличие от сравнения, слова. Просто помните, что порядковый номер означает "это не чувствительно к культуре".

чтобы ответить на ваш конкретный вопрос: нет, но инструмент статического анализа не сможет понять, что ваше входное значение никогда не будет содержать информацию о локали.