// *** before: ***
// a record could not clean up after itself. Anything it owned - a
// handle, an object, a lock - had to be released by hand, and a routine
// with two exits had two places to forget it
var
Guard: TCriticalSection;
begin
Guard := TCriticalSection.Create;
Guard.Enter;
try
if not Ready then
Exit;
Work;
finally
Guard.Leave;
Guard.Free;
end;
end;
// *** in version 10.4: ***
type
TLock = record
private
FSection: TCriticalSection;
public
class operator Initialize(out Dest: TLock);
class operator Finalize(var Dest: TLock);
end;
class operator TLock.Initialize(out Dest: TLock);
begin
Dest.FSection := TCriticalSection.Create;
Dest.FSection.Enter;
end;
class operator TLock.Finalize(var Dest: TLock);
begin
Dest.FSection.Leave;
Dest.FSection.Free;
end;
procedure Work;
begin
var Guard: TLock; // taken here
if not Ready then
Exit; // released here as well - the compiler wraps the
DoWork; // body in try..finally for you
end;