По сути, проблема в следующем:
- У меня есть глобальное состояние ...
- и я хочу изменить это глобальное состояние ...
- но я хочу убедиться, что я его мутировал обратно.
Вы обнаружили, что больно, когда вы делаете это . Мой совет, а не пытаться найти способ сделать это менее больно, попробуйте сначала найти способ не делать болезненную вещь.
Я хорошо знаю, как это тяжело. Когда мы добавили лямбды в C # в v3, у нас была большая проблема. Учтите следующее:
void M(Func<int, int> f) { }
void M(Func<string, int> f) { }
...
M(x=>x.Length);
Как же мы можем успешно это связать? Что ж, то, что мы делаем, это попробуйте оба (x - это int или x - это строка) и посмотрим, что, если таковое имеется, дает нам ошибку. Те, которые не дают ошибок, становятся кандидатами на разрешение перегрузки.
Механизм сообщений об ошибках в компиляторе глобальное состояние . В C # 1 и 2 никогда не было ситуации, в которой мы должны были сказать «связать все тело метода с целью определения наличия ошибок , но не сообщать об ошибках ». В конце концов, в этой программе вы , а не хотите получить ошибку «у int нет свойства с именем Length», вы хотите, чтобы он обнаружил это, запомнил, а не сообщил об этом.
Так что я сделал именно то, что вы сделали. Начните подавлять отчеты об ошибках, но не забудьте остановить подавление отчетов об ошибках.
Это ужасно. Что нам действительно нужно сделать, так это перепроектировать компилятор так, чтобы ошибки были выводом семантического анализатора , а не глобальным состоянием компилятора . Тем не менее, это трудно пропустить через сотни тысяч строк существующего кода, который зависит от этого глобального состояния.
Во всяком случае, о чем-то еще, чтобы думать. Ваше решение «с помощью» приводит к тому, что прыжки прекращаются при возникновении исключения. Это то, что нужно делать? Возможно, это не так. В конце концов, было выдано неожиданное необработанное исключение . Вся система может быть нестабильно . Ни один из ваших внутренних инвариантов состояния не может быть фактически инвариантным в этом сценарии.
Посмотрите на это так: я мутировал в глобальном состоянии. Затем я получил неожиданное необработанное исключение. Я знаю, я думаю, что я снова буду мутировать глобальное состояние! Это поможет! Похоже, очень, очень плохая идея.
Конечно, это зависит от того, что является мутацией глобального состояния. Если это «начать сообщать об ошибках пользователю снова», как это происходит в компиляторе, то правильный , который нужно сделать для необработанного исключения, - снова начать сообщать об ошибках пользователю: в конце концов, мы Вам нужно будет сообщить об ошибке, что у компилятора просто необработанное исключение!
Если, с другой стороны, мутация в глобальное состояние - «разблокировать ресурс и позволить его наблюдать и использовать ненадежный код», то это потенциально ОЧЕНЬ ПЛОХАЯ ИДЕЯ, чтобы автоматически разблокировать его. Это неожиданное необработанное исключение может быть свидетельством атаки на ваш код со стороны злоумышленника, который искренне надеется, что вы собираетесь разблокировать доступ к глобальному состоянию сейчас, когда оно находится в уязвимой, несовместимой форме.