Здравствуйте, alexeiz, Вы писали:
Параллели между Dispose() и деструкторами С++ очевидны, но это все-таки не одна и та же вещь.
Я не сомневаюсь, что в случае C++ выброс исключения во время раскрутки стека приводит к неопределенному поведению. Но приведет ли к неопределенному поведению в .NET — это еще не факт. Я не сомневаюсь, что архитекторами эта проблема обдумывалась (в отличие от некоторых других

) — судить можно хотя бы по приведенному выше факту. Как показал тест — сначала завершаются вызовы Dispose для всех объектов текущего блока, и только затем продолжается раскрутка стека. Происходит это независимо от того, было ли выброшено исключение одним из вызванных методов, или нет.
Единственная неопределенность в данном случае — это вопрос о том, какое из исключений будет обрабатываться далее — то, которое изначально привело к раскрутке стека, или одно из тех, которые возникли во время процесса раскрутки. Судя по результатам эксперимента — обрабатываться будет то, которое было выброшено последним. Это действительно не очень хорошо, т.к. информация о предыдущих исключениях теряется. Однако, неопределенного поведения здесь все-таки нет.
Поэтому мне хотелось бы получить или детальные пояснения, или точные ссылки на оные. Потому что перекапывать целый раздел Юзнета в поисках неких туманных подтверждений твоей правоты — на это времени у меня уж совершенно нет.