Сравнение строк с оператором != дает разные результаты?

Я знаю, что это может показаться очень глупым вопросом, но у меня нет ответов на этот вопрос. Один из наших пользователей недавно сообщил об ошибке, и я понял, что старый фрагмент кода использует != string.Empty, а не IsNullOrEmpty(). Я исправил это с помощью IsNullOrEmpty(), и теперь он работает нормально, но я хотел бы на самом деле понять проблему.

Дело в том, что один и тот же фрагмент кода работает по-разному на разных машинах. У меня есть объект: context["MODE"], который должен быть пустым. Я добавил несколько тестов в журнал:

        contextBuilder.AppendLine("MODE: |" + context["MODE"] + "|");
        contextBuilder.AppendLine("MODE != string.Empty: " + (context["MODE"] != string.Empty));
        contextBuilder.AppendLine("MODE TRIM != string.Empty: " + (context["MODE"].ToString().Trim() != string.Empty));
        contextBuilder.AppendLine("MODE.IsNullOrEmpty: " + string.IsNullOrEmpty(context["MODE"].ToString()));
        contextBuilder.AppendLine("MODE.TRIM.IsNullOrEmpty: " + string.IsNullOrEmpty(context["MODE"].ToString().Trim()));

Вот мои журналы об этих деталях поля:

MODE: || 
MODE != string.Empty: False  
MODE TRIM != string.Empty: False 
MODE.IsNullOrEmpty: True  
MODE.TRIM.IsNullOrEmpty: True

Вот его логи:

MODE: ||
MODE != string.Empty: True
MODE TRIM != string.Empty: False
MODE.IsNullOrEmpty: True
MODE.TRIM.IsNullOrEmpty: True

Как видите, есть одно отличие: MODE != string.Empty для меня False (имеет смысл), True для него! MODE, очевидно, не равен нулю (иначе .ToString() потерпел бы неудачу). Проблема решается с помощью IsNullOrEmpty, но я пытаюсь выяснить, почему именно это не работает на машинах определенных пользователей, а не на других. Обычно с моими тестами у некоторых из нас не было проблем, у других были.

Я действительно не понимаю, что я могу узнать об этом. Почему его режим отличается от null и String.Empty, но IsNullOrEmpty возвращает true? Также обратите внимание, что отделка на самом деле тоже string.Empty.

Благодарю вас!


person Damascus    schedule 11.03.2016    source источник
comment
IsNullOrEmpty на самом деле делает пустую часть, сравнивая Length с 0.   -  person juharr    schedule 11.03.2016
comment
Попробуйте также распечатать context["Mode"].GetType().Name.   -  person juharr    schedule 11.03.2016
comment
Можете ли вы предоставить более подробную информацию о происхождении значения в context["MODE"]? Кроме того, вы убедились, что версии .NET одинаковы на обеих машинах?   -  person Kevin Burdett    schedule 11.03.2016
comment
context["MODE"] — это string в object в обоих случаях. И да, обе машины работают на одной и той же платформе .NET!   -  person Damascus    schedule 14.03.2016


Ответы (1)


Если вы используете ToString(), это указывает на то, что тип context["MODE"] равен object. Если вы сравниваете объект со строкой, используя !=, вы сравниваете ссылки на строки, а не фактические значения строк.

Таким образом, «его режим» — это пустая строка, которая не является той же ссылкой, что и string.Empty.

Не используйте сравнения ссылок на строки; всегда убедитесь, что обе стороны имеют тип string, прежде чем использовать == или !=.

Обратите внимание, что компилятор C# должен был предупредить вас об этом: CS0252: Возможно непреднамеренное сравнение ссылок< /а>

person Daniel    schedule 11.03.2016
comment
@clcto Это правильный вывод, потому что не равно String.Empty вернуло false, что означает, что оно равно равно String.Empty - person Setsu; 11.03.2016
comment
Как я уже сказал, это был старый фрагмент кода, написанный парнем, который заботился о приложении до того, как я присоединился к компании (и да, он пропустил предупреждение!). Мне вот интересно, почему у него такие результаты? Его ввод пуст, но не имеет той же ссылки, что и string.Empty. Однако, когда я обрезаю его, он имеет ту же ссылку! Как это могло произойти? - person Damascus; 14.03.2016
comment
Тип возвращаемого значения Trim()string, поэтому в этом случае компилятор использует сравнение значений. - person Daniel; 14.03.2016