TObject / TFileStream.Free

I am using code like this to save to a file:

procedure TMyClass.SaveFile( filename : String );
var f : TFileStream;
begin
f := TFileStream.Create(filename, fmCreate);
try
SaveToStream(f);
finally
f.Free;
end;
end;

The File stays open (and locked) until I close the debugger. To fix this, I introduced in TFileStream:

method TFileStream.Free;
begin
Close;
end;

But maybe it would be better to implement Free in TObject instead (its “empty” right now) and call the finalizer there. This would make it possible to override Free in any object which inherits from TObject.

What is the official opinion in this matter?

I think, it would be best if TObject would have a
method Free; virtual;

for any descendent class to override if required. Especially when creating objects which link to not-managed resources like files(!) it is required to do some cleanup, not in finalizer because that is executed at a random moment, but at the time the developer decides an object is not required anymore.

Having a virtual “Free” makes it easier to port Delphi code which does some cleanup in “Destroy” by calling the required code in method Free; override; just like the TFileStream above.

A MemoryStream could btw - also remove its buffer in “Free” - to limit the memory loss if the garbage collection does not remove it.

Is it correct that I can mark a pointer value with “weak” that reference will be ignored by the garbage collection?

that’s be. err costly though, i believe. maybe better to have it call Dispose, and have all TObjefts implement that? i’ll bring this up for discussion here.

2 Likes

I would also think, that Dispose would a better solution.
It makes clear what should happen in these Situation.

From my point of view, Dispose is the right thing. But I don’t know if it’s a good solution to have TObject implement Dispose (even when it’s empty), as it makes it harder to know if it’s really an object which must be disposed or not and may tend to end up having using pattern around every single statement.
But in contrary I have to say, I don’t care about TObject, as I’m not really hurt by Delphi compatibility. It’s just my point of vire from a .NET perspective.

1 Like

Julian, about your issue, you can call Close method to “unclock” the file.

And I agree, we should add Free method as virtual and use it, we will discuss about it.
Doing that is easy to port code and follow Delphi pattern.

Thanks a lot!!