我们如何激活(按需)一个对象是另一个对象的属性?

时间:2013-05-23 17:37:48

标签: delphi oop file-io

我正在实现一个对象TTextFile,它是一个使用低级pascal文件函数和OO范例的框架。我想向开发人员添加在同一对象中需要时将其用作TStringList的选项,如下所示:

 TTextFile = class(TObject)
   constructor Create(FileName: String);
   procedure OpenForRead;
   procedure OpenForWrite;
   {...}
   property Content: TStringList;
 end;

但我的问题是我希望Content属性仅在应用程序第一次使用时才使用用户LoadFromFile。不在Create构造中,因为文件可能太大,程序员更喜欢在这种情况下使用其他函数。当Content知道他正在使用的文件不会很大时,就会使用Create

大文件的示例是包含所有客户名称和公民ID的列表。一个非常小的文件的例子是相同的列表,但仅限于当天等待参加的客户端。

是否可以在OO pascal中完成?如果不可能,我将不得不进行一种激活过程或重载Content,并使程序员在使用之前始终检查{{1}}是否已加载。

2 个答案:

答案 0 :(得分:7)

使用延迟初始化的概念。第一次读取Content属性时,加载文件内容,然后保留可用内容,以便后续访问属性不会重新读取文件。

private
  FContent: TStrings;
  function GetContent: TStrings;
public
  property Content: TStrings read GetContent;

function TTextFile.GetContent: TStrings;
begin
  if not Assigned(FContent) then begin
    FContent := TStringList.Create;
    try
      FContent.LoadFromFile(FFileName);
    except
      FContent.Free;
      FContent := nil;
      raise;
    end;
  end;
  Result := FContent;
end;

答案 1 :(得分:2)

当然这是可能的。

更改您的班级声明:

TTextFile = class(TObject)
   constructor Create(FileName: String);
   procedure OpenForRead;
   procedure OpenForWrite;
   function GetContent: TStringList;
   {...}
   property Content: TStringList read GetContent;
 end;    

并实施它:

function TTextFile.GetContent: TStringList;
begin
  Result := TStringList.Create;
  Result.LoadFromFile(FFileName);  // Presumes FileName is stored in FFileName in constructor
end;