In Delphi, I created a small class like this:
TFilesSorter = class
public
constructor Create(ExtOrderList: TStrings);
function SoryByExt(List: TStringList; Index1, Index2: Integer): Integer;
private
ExtOrder: TStrings;
end;
I created a class because the SoryByExt
function needs an ordered list of extensions (ExtOrder
) used in the sort.
When I try to use my class function with CustomSort
, like this:
FilesSorter := TFilesSorter.Create(ExtensionsList);
try
SomeTStringList.CustomSort(FilesSorter.SoryByExt);
finally
FilesSorter.Free;
end;
I get an error:
E2009 Incompatible types: 'regular procedure and method pointer'
Now I understand why (it works only with a non-class function), but I'm wondering how to use CustomSort
when you need another variable (my ordered list of extension used during the sort process) without using global variables? I want to separate the responsibilities and not have shared variables.
What is the proper way to do this (I use Delphi 11)?
TStringList.CustomSort()
does not support non-static class methods for its sort routine. So, when using a standard TStringList
, if you need to access an external variable from inside your sort routine then it would have to be a global variable. Or, since the sort routine does have access to the TStringList
that is being sorted, you could store a pointer to the external variable in one of the entries of the TStringList.Objects
property (if you are not using it for something else, that is).
Otherwise, an alternative option would be to derive a new class from TStringList
and add whatever members you want to it, and then replace the original TStringList
with your custom TStringList
. That way, your sort routine can then typecast its List
parameter to that derived class to access the extra members you added to it.
For example, in this case, TFilesSorter
itself could be the new TStringList
descendant, eg:
TFilesSorter = class(TStringList)
public
constructor Create(ExtOrderList: TStrings);
function SoryByExt(List: TStrings);
private
ExtOrder: TStrings;
end;
constructor TFilesSorter.Create(ExtOrderList: TStrings);
begin
inherited Create;
ExtOrder := ExtOrderList;
end;
function doSoryByExt(List: TStringList; Index1, Index2: Integer): Integer;
begin
// use TFilesSorter(List).ExtOrder to compare
// List.Strings[Index1] with List.Strings[Index2]
// as needed...
Result := ...;
end;
function TFilesSorter.SoryByExt(List: TStrings);
begin
Self.Assign(List);
Self.CustomSort(doSoryByExt);
List.Assign(Self);
end;
...
FilesSorter := TFilesSorter.Create(ExtensionsList);
try
FilesSorter.SoryByExt(SomeTStringList);
finally
FilesSorter.Free;
end;