Оператор using - это просто синтаксический сахар для блока try finally. Вы можете получить то, что вы хотите, написав try наконец полностью, а затем добавив оператор catch для обработки вашего особого случая:
try
{
IDisposable x = new MyThing();
}
catch (Exception exception) // Use a more specific exception if possible.
{
x.ErrorOccurred = true; // You could even pass a reference to the exception if you wish.
throw;
}
finally
{
x.Dispose();
}
Внутри MyThing вы можете сделать это, если хотите, например:
class MyThing : IDisposable
{
public bool ErrorOccurred() { get; set; }
public void Dispose()
{
if (ErrorOccurred) {
RollBack();
} else {
Commit();
}
}
}
Примечание: мне также интересно, почему вы хотите это сделать. У него какой-то кодовый запах. Метод Dispose предназначен для очистки неуправляемых ресурсов, а не для обработки исключений. Возможно, вам лучше написать код обработки исключений в блоке catch, а не в dispose, и если вам нужно поделиться кодом, создайте несколько полезных вспомогательных функций, которые вы можете вызывать из обоих мест.
Вот лучший способ сделать то, что вы хотите:
using (IDisposable x = new MyThing())
{
x.Foo();
x.Bar();
x.CommitChanges();
}
class MyThing : IDisposable
{
public bool IsCommitted { get; private set; }
public void CommitChanges()
{
// Do stuff needed to commit.
IsCommitted = true;
}
public void Dispose()
{
if (!IsCommitted)
RollBack();
}
}