Как я могу остановить выполнение в отладчике Visual Studio, когда частная переменная-член меняет значение? - PullRequest
5 голосов
/ 05 февраля 2009

Допустим, у моего класса есть закрытая целочисленная переменная count.

Я уже достиг точки останова в своем коде. Теперь, прежде чем нажать «продолжить», я хочу сделать так, чтобы отладчик остановился, когда счетчик получит новое назначенное ему значение.

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

Ответы [ 5 ]

3 голосов
/ 06 февраля 2009

То, что вы ищете, невозможно в управляемом коде. В C ++ это называется точкой останова данных. Это позволяет вам ломаться всякий раз, когда блок памяти изменяется работающей программой. Но это доступно только в чистом родном коде C ++.

Короткая версия того, почему это не реализовано, состоит в том, что в управляемом коде намного сложнее. Родной код приятен и предсказуем. Вы создаете память, и она не перемещается, пока вы не создадите новый объект (или явно не скопируете память).

Управляемый код намного сложнее, потому что это язык для сборки мусора. CLR обычно перемещает объекты в памяти. Поэтому просто смотреть немного памяти недостаточно. Требуется взаимодействие с GC.

Это только одна из проблем с реализацией управляемых точек останова.

0 голосов
/ 06 февраля 2009

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

Сделайте его свойством другого класса, создайте экземпляр класса и установите точку останова для свойства.

Вместо ...

test()
{
   int i = 3;
   ...etc...
   i = 4;
}

... есть ...

class Int
{
  int m;
  internal Int(int i) { m = i; }
  internal val { set { m = value; } get { return m; } }
}

test()
{
  Int i = new Int(3);
   ...etc...
   i.val = 4;
}

Дело в том, что с использованием C # фактическое расположение в памяти всего перемещается непрерывно: и поэтому отладчик не может легко использовать регистр отладки ЦП 'break on memory access', и отладчику легче вместо этого реализуйте точку останова расположения кода.

0 голосов
/ 05 февраля 2009

Единственный способ сделать это - щелкнуть правой кнопкой мыши по переменной и выбрать «Найти все ссылки». Как только он найдет все ссылки, вы можете создать новую точку останова в каждой точке кода, где переменной присваивается значение. Вероятно, это будет работать довольно хорошо, если только вы не передадите переменную по ссылке на другую функцию и не измените ее значение. В этом случае вам потребуется какой-то способ наблюдения за определенной точкой в ​​памяти, чтобы увидеть, когда она изменилась. Я не уверен, существует ли такой инструмент в VS.

0 голосов
/ 05 февраля 2009

Как прокомментировал ChrisW. Вы можете установить «Точку останова данных», но только для собственного (неуправляемого) кода. Сборщик мусора будет перемещать выделенные блоки памяти при запуске сборщика мусора. Таким образом, точки останова данных невозможны для управляемого кода.

В противном случае нет. Вы должны инкапсулировать доступ к своему элементу, для которого вы хотите «разбить на изменение». Поскольку он уже является частным участником, я предлагаю следовать предложению Кибби об установке точек останова везде, где он используется.

0 голосов
/ 05 февраля 2009

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

По сути, я бы сказал, что, поскольку приватное поле является только хранилищем, его нельзя разбить, потому что приватное поле не является разрушаемой инструкцией.

...