" using" Конструкция выглядит невероятно удобной для ситуаций, требующих как начальных, так и разделенных конечных частей.
Быстрый пример для иллюстрации:
using (new Tag("body")) {
Trace.WriteLine("hello!");
}
// ...
class Tag : IDisposable {
String name;
public Tag(String name) {
this.name = name;
Trace.WriteLine("<" + this.name + ">");
Trace.Indent();
}
public void Dispose() {
Trace.Unindent();
Trace.WriteLine("</" + this.name + ">")
}
}
Начальная часть определяется как конструктор, конечной частью является метод Dispose.
Однако, несмотря на привлекательность, эта конструкция имеет серьезное предостережение, которое исходит из того факта, что метод Dispose вызывается из блока finally. Итак, есть 2 проблемы:
-
Вам следует избегать бросать исключения из блока finally, потому что они будут переопределять исходное исключение, которое должно было быть уловлено.
-
Не существует способа узнать внутри метода Dispose, если исключение было выбрано ранее между "началом" и "завершением", и, следовательно, нет возможности обработать "конец" соответственно.
Эти две вещи делают использование этой конструкции непрактичным, что является очень грустным фактом. Теперь мои вопросы:
-
Насколько я правильно понимаю проблемы? Это как работает "использование"?
-
Если это так, есть ли способ преодолеть эти проблемы и использовать практическое использование "использования", кроме того, из чего он был первоначально предназначен (освобождение ресурсов и очистка)
-
Если нет практического способа "использования" для использования таким образом. Каковы альтернативные подходы (для обеспечения соответствия контекста некоторому коду с начальной и конечной частями)?