这段 Delphi 与对象函数数组相关的代码可以更简洁吗?
Can this Delphi code related to an array of function of object be made cleaner?
关于 Delphi 中的这个功能:
function TAudioFileMetadata.LoadTags(const Filename: String; var LastError: Integer; var DetectedFormat: TAudioFormat): Boolean;
type
TLoadFromFunction = function (const Filename: String; var LastError: Integer): Boolean of object;
TLoadFrom = record
Format: TAudioFormat;
Process: TLoadFromFunction;
end;
var
i: Byte;
LoadOrder: array [1..6] of TLoadFrom;
begin
DetectedFormat := afUnknown;
LoadOrder[1].Format := afMp3;
LoadOrder[1].Process := LoadFromMp3;
//...
LoadOrder[6].Format := afApe;
LoadOrder[6].Process := LoadFromApe;
for i := Low(LoadOrder) to High(LoadOrder) do
begin
Result := LoadOrder[i].Process(Filename, LastError);
if Result then
begin
DetectedFormat := LoadOrder[i].Format;
break;
end;
end;
end;
如何改进我的实施?我可以一次性 create/fill LoadOrder
数组吗(或者至少每个 TLoadFrom
不使用 2 行)?可以使用 const
数组吗(我不这么认为)?
Delphi 闭包 (function|procedure ... of object
) 由 TMethod
记录支持,您可以在运行时对其进行操作。所以尝试这样的事情:
function TAudioFileMetadata.LoadTags(const Filename: String; var LastError: Integer; var DetectedFormat: TAudioFormat): Boolean;
type
TLoadFromFunction = function (const Filename: String; var LastError: Integer): Boolean of object;
TLoadFrom = record
Format: TAudioFormat;
ProcessAddr: Pointer;
end;
const
LoadOrder: array[1..6] of TLoadFrom = (
(Format: afMp3; ProcessAddr: @TAudioFileMetadata.LoadFromMp3),
...
(Format: afApe; ProcessAddr: @TAudioFileMetadata.LoadFromApe)
);
var
i: Byte;
Process: TLoadFromFunction;
begin
DetectedFormat := afUnknown;
TMethod(Process).Data := Self;
for i := Low(LoadOrder) to High(LoadOrder) do
begin
TMethod(Process).Code := LoadOrder[i].ProcessAddr;
Result := Process(Filename, LastError);
if Result then
begin
DetectedFormat := LoadOrder[i].Format;
Exit;
end;
end;
end;
关于 Delphi 中的这个功能:
function TAudioFileMetadata.LoadTags(const Filename: String; var LastError: Integer; var DetectedFormat: TAudioFormat): Boolean;
type
TLoadFromFunction = function (const Filename: String; var LastError: Integer): Boolean of object;
TLoadFrom = record
Format: TAudioFormat;
Process: TLoadFromFunction;
end;
var
i: Byte;
LoadOrder: array [1..6] of TLoadFrom;
begin
DetectedFormat := afUnknown;
LoadOrder[1].Format := afMp3;
LoadOrder[1].Process := LoadFromMp3;
//...
LoadOrder[6].Format := afApe;
LoadOrder[6].Process := LoadFromApe;
for i := Low(LoadOrder) to High(LoadOrder) do
begin
Result := LoadOrder[i].Process(Filename, LastError);
if Result then
begin
DetectedFormat := LoadOrder[i].Format;
break;
end;
end;
end;
如何改进我的实施?我可以一次性 create/fill LoadOrder
数组吗(或者至少每个 TLoadFrom
不使用 2 行)?可以使用 const
数组吗(我不这么认为)?
Delphi 闭包 (function|procedure ... of object
) 由 TMethod
记录支持,您可以在运行时对其进行操作。所以尝试这样的事情:
function TAudioFileMetadata.LoadTags(const Filename: String; var LastError: Integer; var DetectedFormat: TAudioFormat): Boolean;
type
TLoadFromFunction = function (const Filename: String; var LastError: Integer): Boolean of object;
TLoadFrom = record
Format: TAudioFormat;
ProcessAddr: Pointer;
end;
const
LoadOrder: array[1..6] of TLoadFrom = (
(Format: afMp3; ProcessAddr: @TAudioFileMetadata.LoadFromMp3),
...
(Format: afApe; ProcessAddr: @TAudioFileMetadata.LoadFromApe)
);
var
i: Byte;
Process: TLoadFromFunction;
begin
DetectedFormat := afUnknown;
TMethod(Process).Data := Self;
for i := Low(LoadOrder) to High(LoadOrder) do
begin
TMethod(Process).Code := LoadOrder[i].ProcessAddr;
Result := Process(Filename, LastError);
if Result then
begin
DetectedFormat := LoadOrder[i].Format;
Exit;
end;
end;
end;