Безжизненное сравнение строк в С#

Скажем, у меня две строки: a и b. Чтобы сравнить, имеют ли значения a и имеют одинаковые значения, когда случай игнорируется, я всегда использовал:

// (Assume a and b have been verified not to be null)

if (a.ToLower() == b.ToLower())

Однако, используя Reflector, я видел это несколько раз в .NET Framework:

// (arg three is ignoreCase)

if (string.Compare(a, b, true) == 0)

Я тестировал, что быстрее, а ToLower() бить Compare() каждый раз с использованием строк, которые я использовал.

Есть ли причина для Compare() вместо ToLower()? Что-то о другом CultureInfo? Я почесываю голову.

Ответ 1

В разделе "Примечания" статьи

Ответ 2

Главное, что вас беспокоит, это не производительность, не правильность, и с этого аспекта метод, который вы, вероятно, хотите использовать для нечувствительного к регистру, либо:

string.Compare(a, b, StringComparison.OrdinalIgnoreCase) == 0;

или

a.Equals(b, StringComparison.OrdinalIgnoreCase)

(Первый полезен, если вы знаете, что строки могут быть нулевыми, а последнее проще писать, если вы уже знаете, что хотя бы одна строка не равна нулю. Я никогда не тестировал производительность, но предполагаю, что это будет аналогично.)

Ordinal или OrdinalIgnoreCase - это безопасная ставка, если вы не знаете, что хотите использовать другой метод сравнения; чтобы получить информацию, необходимую для принятия решения прочитать эту статью в MSDN.

Ответ 3

При сравнении строк вы должны всегда использовать явный член StringComparison. Строковые функции несколько непоследовательны в том, как они предпочитают сравнивать строки. Единственный способ гарантировать сравнение используется: a) запомнить все из них (это включает в себя как вас, так и всех в вашей команде) или b) использовать явное сравнение для каждой функции.

Гораздо лучше быть явным и не полагаться на отличное знание группы. Ваши товарищи по команде поблагодарят вас за это.

Пример:

if ( StringComparison.OrdinalIgnoreCase.Equals(a,b) )

Использование ToLower для сравнения имеет 2 проблемы, которые я могу придумать с головы.

  • Он выделяет память. Функции сравнения не должны выделять память, если они абсолютно не нужны.
  • Строки можно опустить несколькими способами. Наиболее заметный Порядковый или Культурный Чувствительный ниже. Каким образом работает .ToLower()? Лично я не знаю. Гораздо лучше передать явную культуру, чем полагаться на дефолт.

Ответ 4

ToLower() не является функцией сравнения, она помещает строку в нижний регистр. Когда оператор == используется для объектов String в С#, он оптимизируется компилятором. В основе оба зависят от System.String.Equals, как показано в Reflector.

Ответ 6

Может ли ваш пост ваш тест, который показывает вызов ToLower(), быстрее, чем сравнение без учета регистра? Мои тесты показывают обратное, чтобы быть правдой! Независимо от того, имеются ли другие плакаты о правильности.