Should I use String instead of TFilename?
When passing filename parameters to procedures/functions, should I use TFilename or String.
If there is a difference, what is it, and what are then potential ramifications if using a String?
procedure TForm1.OpenFile(const AFilename : String); begin //Open the file if it exists ... end;
I think TFilename should be used when developing components because that way IDE can show it's property editor (TOpenDialog will be shown when clicked on ellipsis in the property inspector).
Other than this there is basically no difference which one to use. Remember that if you use TFilename you must add SysUtils to your uses clause.
The only practical difference between string and TFileName types in a plain code is in passing an argument by reference; the following code
procedure GetFileName(var FileName: TFileName); begin FileName:= 'abcd.abc'; end; procedure TForm1.Button2Click(Sender: TObject); var S: string; begin GetFileName(S); end;
does not compile with error
[DCC Error] E2033 Types of actual and formal var parameters must be identical
Maybe this is a bit too obvious, but using the string type doesn't communicate anything about the intended usage of a variable. But when you encounter a variable declared as a TFileName, there's a lot more detail communicated right there.
The same principle applys to other basic types like Integer, Cardinal, Double etc. Instead you might want to consider using aliases for these like TCustomerID, THashValue, TInterestRate, etc. as these communicate much clearer what the intended usage of these variables is.
This improves readablility, and also allows for changing the base-type when needed, without having to touch any code using the type... just a recompile and you're done (but do be carefull with binary compatibility ofcourse).
Hmm, My strong preference is for const AFilename: String; For the reason that especially for larger projects, if you ever need to add source code from another coder, if they have used lots of custom types like TCustomerID, THashValue, TInterestRate, instead of Integer, Cardinal, Double, then you have lots of the above mentioned E2033 to resolve.
Even lots of delphi built in source code doesn't use TFileName, like:
function MatchesMask(const Filename, Mask: string): Boolean;
Furthermore if I have a variable defined like AFileName: TFileName; then its obvious its a filename & the named type doesn't add any readability for me, if anything in some cases it makes code less readable, because you have to click through to check what actual variable its derived from.