I recently stumbled over a problem caused by some very old code I wrote which was obviously assuming that interface references used in a with
statement would be released as soon as the with
-block is left - kind of like an implicit try-finally
-block (similar to C#'s using
-statement if I understood correctly).
Apparently (in Delphi 2009) this is not (no longer?) the case. Does anyone know when this happened? Or was my code just plain wrong to begin with?
To clarify, here's a simplified example:
type
IMyIntf = interface;
TSomeObject = class(TInterfacedObject, IMyIntf)
protected
constructor Create; override; // creates some sort of context
destructor Destroy; override; // cleans up the context created in Create
public
class function GetMyIntf: IMyIntf; //a factory method, calling the constructor
end;
procedure TestIt;
begin
DoSomething;
with (TSomeObject.GetMyIntf) do
begin
DoStuff;
DoMoreStuff;
end; // <- expected: TSomeObject gets destroyed because its ref.count is decreased to 0
DoSomethingElse;
end; // <- this is where TSomeObject.Destroy actually gets called
Whenever somebody started the old "with
is evil" argument this was always the one example I had in mind which kept me going "Yes, but...". Seems like I was wrong... Can anyone confirm?
The with
preserved word in Pascal/Delphi is only used for easily accessing the members of records or objects/classes (i.e. in order not to mention the record's/object's/class's name). It's very different from the C# with
that relates to garbage collection. It has existed in the Pascal language since the day records
were born, to simplify code calling to many data members (back then simply called "fields").
To summarize, with
has nothing to do with garbage collection, release of memory or destruction of object instances. Objects that are constructed at the with
header could just have been initialized in a separate code line before, it's the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With