Почему условие прерывания отладчика позволяет присваивать-утверждение как условие bool?

Это очень опасно, поэтому я задаюсь вопросом, почему это разрешено. Поскольку мне часто приходится переключаться между VB.NET и С#, я иногда добавляю условия точки останова, например следующее:

foo = "bah"

Я хочу остановиться, если переменная string foo равна "bah, поэтому правильным способом было использовать foo == "bah" вместо foo = "bah".

Но он "работает". Вы не получаете никаких предупреждений или ошибок во время компиляции или выполнения. Но на самом деле это изменяет переменную foo, она делает ее всегда "bah", даже если она имела другое значение. Так как это происходит тихо (точка останова никогда не попадает), это невероятно опасно.

Почему это разрешено? Где моя ошибка в рассуждении (кроме путаницы синтаксиса С# и VB.NET)? В С# (в отличие от VB.NET) оператор присваивания возвращает значение, которое было назначено, а не bool, но string в этом случае. Но условие точки останова должно быть bool, если вы установите флажок "Истина".

Вот небольшой пример "программы" и скриншоты из моей (немецкой) среды IDE:

static void Main()
{
    string foo = "foo";
    // breakpoint with assignment(foo = "bah") instead of comparison(foo == "bah"):
    Console.WriteLine(foo);  // bah, variable is changed from the breakpoint window
}

Диалог состояния точки останова:

enter image description here

Код как изображение, включая точку останова:

enter image description here

Ответы

Ответ 1

Это автоматическое следствие синтаксиса С#, общего в языковой группе фигурных скобок. Назначение также является выражением, результатом которого является значение операнда правой стороны. Отладчик не относится ни к выражениям, имеющим побочные эффекты, ни к простому, чтобы их подавить. Его можно обвинить в том, что он не проверяет, что выражение имеет результат bool, однако отладчик не имеет полноразмерного парсера языка С#. Это может быть исправлено в VS2015 благодаря проекту Roslyn. [Примечание: см. Добавление внизу].

Также основная причина, по которой языкам фигурных скобок нужен отдельный оператор для равенства, == vs =. Что само по себе должно отвечать за ошибки в миллиард долларов, каждый программист C совершает эту ошибку хотя бы один раз.

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

Имейте в виду, что это действительно полезно. Он позволяет временно обходить ошибку, заставляя значение переменной и позволяя продолжить отладку и сосредоточиться на другой проблеме. Или создать тестовое условие. Это очень полезно. В предыдущем жизненном цикле я написал компилятор и отладчик и реализовал "точки трассировки". Обнаружен тот же сценарий случайно и оставил его на месте. Он работал на хосте, который в значительной степени полагался на государственные машины, переопределяя переменную состояния, в то время как отладка была невероятно полезной. Авария, нет, не очень полезно:)


Заметка о том, что наблюдают другие пользователи SO, зависит от используемого вами механизма отладки. Соответствующим вариантом в VS2013 являются флажок "Инструменты + Параметры", "Отладка", "Общие", "Использовать управляемый режим совместимости". Тот же вариант существует в VS2012, он имел несколько другое имя (не помню). При тике вы получаете более старый механизм отладки, который по-прежнему совместим с С++/CLI. Тот же, что используется в VS2010.

Итак, чтобы обходной путь для VS2013, отключите опцию, чтобы отладчик мог проверить, что выражение создает результат bool. Вы получаете еще несколько полезных свойств с помощью этого нового механизма отладки, например, для просмотра значений возвращаемых методов и поддержки Edit + Continue для 64-битных процессов.

Ответ 2

Я могу не согласиться с баггией характера этого поведения. Немного примеров, где для отладки в моей жизни, если было полезно:
1. Другой поток изменяет что-то в вашем коде. 2. Другое обновленное значение службы в db
Поэтому я полагаю, что для случаев синхронизации это может быть полезной функцией, но я согласен, что это может вызвать проблемы.

Ответ 3

В Visual Studio 2019 выражения назначения переменных в условиях точки останова больше не работают.

Выражение будет оцениваться по значению, но побочные эффекты, такие как назначение переменной, отбрасываются.

https://developercommunity.visualstudio.com/content/problem/715716/variables-cannot-be-assigned-in-breakpoint-conditi.html