In my source I see and use often a construction like:
with TSQLDataSet.Create(nil) do try
//Dosomething, get a result from a query.
finally
Free;
end;
But I also often see the construction:
with TSQLDataSet.Create(nil) do begin
//Dosomething, get a result from a query.
end;
If I create objects with a with contruction, do I need to free them or is that automatic at the end of the with-block?
You need to free
.
Because Class.Create
is just an expression, and Delphi cannot know which expression the resulting value came from.
You can just read VCL sources - there is always explicit .Free
.
And you can think of non-object example:
var r: record .... end;
with r do begin
...
end;
If Delphi tried to free everything at with
end - then it would try to free
non-object ?
with SomeObjectFactory.GetMeAnObject do begin
...
end;
Here you create object not by constructor, but by some function. And this function is not different from TLabel.Font
or TDataSet.FieldByName
.
Should Delphi free
it or not here ?
To avoid the risky guesswork and keep it uniform - with
is just with
. It is just an alias. Nothing more. It was designed back in 1974 and is does not clone functionality of latest .Net/Scala Using(x){..}
constructs.
What you maybe saw were constructs like
with TForm.Create(Application) do ...;
with TLabel.Create(MainForm.Panel1) do ...;
That is very different - that does insert newly created control as belonging to an owner. The owner would free
all its owned components when it is free
d itself. But that does not use Create(nil)
. And when it still does - then inside the with
block you would see some explicit call, binding the object to some container/parent (though that is very fragile in case of exceptions between .Create
and binding).