我知道的非常不时髦的标题。
我有一系列文本行,我需要按特定顺序执行某些操作。通过定义以下记录结构,我想出了一种方法:
TProcessOrderRecord = record
RecordTypes: TByteSet;
InitialiseProcedure: TPreScanProc;
ProcessProcedure: TProcessRecord;
FinaliseProcedure: TEndScanProc;
end;
AProcessOrderArray = array of TProcessOrderRecord;
Initialise 倾向于调用一个构造函数,该构造函数将填充宿主对象中的一个字段。
Process 将是对象上的一个过程,它将为每个与 RecordTypes 中的记录类型匹配的文本行调用。
Finalize 将倾向于调用析构函数并可能在它知道已处理完整的记录集时进行任何检查。
处理这个数组的方法非常简单:
procedure TImport.ScanTransferFile;
var
i: integer;
lArrayToProcess: AProcessOrderArray;
begin
lArrayToProcess := SetUpProcessingOrder(NLPGApp.ImportType);
for i := low(lArrayToProcess) to high(lArrayToProcess) do
begin
ProcessRecordType(lArrayToProcess[i].RecordTypes, lArrayToProcess[i].InitialiseProcedure, lArrayToProcess[i].ProcessProcedure, lArrayToProcess[i].FinaliseProcedure);
end;
end;
procedure TImport.ProcessRecordType(const RecordTypesToFind: TByteSet; PreScanProcedure: TPreScanProc; OnFindRecord: TProcessRecord; OnCompleteScan: TEndScanProc);
var
lLineOfText: string;
lIntegerRecordID: byte;
begin
if Assigned(PreScanProcedure) then PreScanProcedure;
try
if assigned(OnFindRecord) then
begin
Reader.GoToStartOfFile;
while not Reader.EndOfFile do
begin
lLineOfText := Reader.ReadLine;
lIntegerRecordID := StrToIntDef(GetRecordID(lLineOfText), 0);
if lIntegerRecordID in RecordTypesToFind then
begin
try
OnFindRecord(lLineOfText);
except
on E: MyAppException do
begin
// either raise to exit or log and carry on
end;
end;
end;
end;
end;
finally
// OnCompleteScan usually contains calls to destructors, so ensure it's called
if Assigned(OnCompleteScan) then OnCompleteScan;
end;
end;
我的问题是我想这样定义一个记录:
RecordTypes = [10]
InitialiseProcedure = ProcToCreateFMyObj
ProcessProcedure = FMyObj.do
FinaliseProcedure = ProcToFreeFMyObj
这编译得很好,但是当 ProcessProcedure 被调用时,因为在设置 ProcessProcedure 时 FMyObj 为 nil,即使现在设置了 FMyObj,TMyObj 的实例也是 nil。有没有什么干净的方法可以让记录在调用时而不是在第一次分配时指向 FMyObj 的实例?
目前我已经在宿主对象上使用了“调用者”方法,然后可以在需要时调用 FMyObj 实例,但这会创建一个包含许多单行方法的相当臃肿的对象。
编辑以澄清/复杂化问题
有时一个实例FObj
可以处理不止一种类型的记录(通常如果它们具有主从关系)。在这种情况下,InitialiseProcedure
第一个记录类型将创建FObj
,FinaliseProcedure
第二个记录将释放FObj
,并且每个记录ProcessProcedure
可以引用FObj
(do1
和do2
) 的不同过程。