delphi - 如何在对象存在之前将记录字段设置为 'Procedure of object'以便其可以运行

标签 delphi delphi-2006

我知道这个标题非常不活泼。

我有一系列文本行,我需要按特定顺序对其执行特定操作。我想出了一种通过定义以下记录结构来实现此目的的方法:

TProcessOrderRecord = record
  RecordTypes:       TByteSet;
  InitialiseProcedure: TPreScanProc;
  ProcessProcedure:    TProcessRecord;
  FinaliseProcedure:   TEndScanProc;
end;

AProcessOrderArray = array of TProcessOrderRecord;

初始化倾向于调用构造函数来填充宿主对象中的字段。

Process 将是对象上的一个过程,将为与 RecordTypes 中的记录类型之一匹配的每个文本行调用。

当 Finalise 知道完整的记录集已被处理时,它往往会调用析构函数并可能执行任何检查。

处理这个数组的方法非常简单:

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的不同过程(do1do2)。

最佳答案

At present I have resorted to having 'caller' methods on the host object which can then call the FMyObj instance when needed, but this is creating quite a bloated object with lots of single-line methods.

这是正确的解决方案。由于实例在初始化时不可用,因此您别无选择。

当您使用 of object 时,您正在定义一个名为 method pointer 的东西。 。当您分配给方法指针类型的变量时,实例将在分配点被捕获。没有机制可以动态解析与方法指针关联的实例。实现这一目标的唯一方法是使用运行时委托(delegate),这就是您当前正在做的事情。通常情况下,会使用另一层间接来解决问题!

包含许多方法的记录看起来非常像界面。我怀疑最优雅的解决方案将涉及一个接口(interface)。也许在调用时您可以调用一个返回接口(interface)的函数。该函数将在调用时使用 FMyObj 的值来定位适当的接口(interface)。

关于delphi - 如何在对象存在之前将记录字段设置为 'Procedure of object'以便其可以运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15253864/

相关文章:

delphi - FireDac 并使用 system.abort 中止之前的帖子

delphi - 了解共享内存

delphi - TGM map 访问被拒绝

linux - 在 CentOS_7 1908 上使用 FMXLinux 时出现错误

delphi - 从 Delphi 2006 升级到 Delphi XE 后关闭应用程序时出现无效指针异常

delphi - 无状态 HTTP session 中的进度反馈

delphi - Delphi 2009之前如何处理UTF-8和ANSI转换?

delphi - 我无法在打开和保存对话框中获得 Delphi 上下文相关帮助

delphi - 如何为相互依赖的记录定义隐式转换运算符?

Delphi - 加载 JPEG 并将输出打印为黑色方 block ?