How would you "extract" nested try/finally blocks from a routine into a reusable entity? Say I have
procedure DoSomething; var Resource1: TSomeKindOfHandleOrReference1; Resource2: TSomeKindOfHandleOrReference2; Resource3: TSomeKindOfHandleOrReference3; begin AcquireResource1; try AcquireResource2; try AcquireResource3; try // Use the resources finally ReleaseResource3; end; finally ReleaseResource2; end; finally ReleaseResource1; end; end; and want something like
TDoSomething = record // or class strict private Resource1: TSomeKindOfHandleOrReference1; Resource2: TSomeKindOfHandleOrReference2; Resource3: TSomeKindOfHandleOrReference3; public procedure Init; // or constructor procedure Done; // or destructor procedure UseResources; end; procedure DoSomething; var Context: TDoSomething; begin Context.Init; try Context.UseResources; finally Context.Done; end; end; I want this to have the same exception-safety as the nested original. Is it enough to zero-initialize the ResourceN variables in TDoSomething.Init and do some if Assigned(ResourceN) then checks in TDoSomething.Done?
try / finally, determining which resource wasn't acquired, and disposing of the ones that were? I guess that's where you're headed with your approach though.