Подтвердить что ты не робот

С# string.IndexOf() возвращает неожиданное значение

Этот вопрос относится к устройствам С#,.net Compact Framework 2 и Windows CE 5.

Я столкнулся с ошибкой в ​​DLL.net, которая использовалась на самых разных устройствах CE в течение многих лет, без каких-либо проблем. Внезапно на новом устройстве Windows CE 5.0 эта ошибка появилась в следующем коде:

string s = "Print revenue receipt"; // has only single space chars 
int i = s.IndexOf("  "); // two space chars

Я ожидаю, что я будет -1, однако это было верно только до сегодняшнего дня, когда indexOf неожиданно вернул 5.

Поскольку это поведение не возникает при использовании

int i = s.IndexOf("  ", StringComparison.Ordinal);

я вполне уверен, что это феномен феномена, основанного на культуре, но я не могу распознать разницу, которое делает это новое устройство. Это в основном идентичная версия известного устройства (просто быстрый процессор и новая плата).

Оба устройства:

  • запустить Windows CE 5.0 с идентичной локализацией
  • Отчеты System.Environment.Version 2.0.0045.0
  • CultureInfo.CurrentUICulture и CultureInfo.CurrentCulture report 'en-GB' (также тестируется с де-DE)
  • "все" связанные ключи реестра равны.

Новое устройство имело предустановленную CF 3.5, чьи файлы GAC, которые я экспериментально переименовал, без изменений описанного поведения. Поскольку во время выполнения всегда сообщается версия 2.0.7045.0, я предполагаю, что эти сборки не имеют никакого эффекта.

Хотя это не сложно исправить, я не могу этого вынести, когда что-то кажется волшебным. Любые намеки на то, что мне не хватает?

Изменить: он становится незнакомцем и незнакомцем, см. снимок экрана: screenshot

Еще одно: screenshot

4b9b3361

Ответ 1

Я считаю, что у вас уже есть ответ, используя порядковый поиск

    int i = s.IndexOf("  ", StringComparison.Ordinal);

Вы можете прочитать небольшой раздел в документации для String Class, который должен сказать это по этому вопросу:

Строковые методы поиска, такие как String.StartsWith и String.IndexOf, также могут выполнять культурно-чувствительные или упорядоченные сравнения строк. Следующий пример иллюстрирует различия между порядковыми и культурно-чувствительными сравнениями с использованием метода IndexOf. Культурно-чувствительный поиск, в котором текущая культура является английским (Соединенные Штаты), считает подстроку "oe" соответствующей лигатуре "œ". Поскольку мягкий дефис (U + 00AD) является символом нулевой ширины, поиск рассматривает мягкий дефис как эквивалент Empty и находит совпадение в начале строки. С другой стороны, порядковый поиск не находит соответствия в любом случае.

Ответ 2

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

int i = s.IndexOf("  ", StringComparison.InvariantCulture);

Ответ 3

Ссылка на http://msdn.microsoft.com/en-us/library/k8b1470s.aspx гласит:

"Символьные наборы включают в себя неосведомленные символы, которые являются символами, которые не учитываются при выполнении лингвистического или культурно-чувствительного сравнения. В чувствительном к культуре поиске, если значение содержит незнатный символ, результат эквивалентен поиску с этим символом удален".

Это из 4.5 ссылок, ссылки из предыдущих версий не содержат ничего подобного.

Итак, позвольте мне угадать: они изменили правила с 4,0 до 4,5, и теперь второе пространство из двух пространственных последовательностей считается "неосведомленным персонажем" - по крайней мере, если движок распознает вашу строку как текст на английском языке (например, в строке примера s), в противном случае нет.

И как-то на вашем новом устройстве вместо dll ожидаемой версии 2.0 используется dll.

Дикая догадка, я знаю:)