检索对象中的Classed TObjectList

时间:2014-05-15 18:50:31

标签: delphi delphi-xe2

我创建了一个名为TRecord的类来存储数据。我创建了另一个包含TRecord类作为对象列表的类。我使用TRecord在对象列表中添加记录,然后在完成后将其设置为父类TTableStore.FManyrecords。

我可以检索列表,COUNT显示相同数量的记录,但不会让我检索每条记录。

问题是我无法访问记录程序/方法,甚至无法定义记录的检索。请参见伪代码的最后一行:

TRecord = class(TObject)
  private
    FDescription : Variant;
    FDirectDeposit : Double;
  public
    function  GetDescription : Variant;
    function  GetDirectDeposit : Double;
    procedure SetDescription(Value: Variant; DoValidation: Boolean = True);
    procedure SetDirect(Value: Double; DoValidation: Boolean = True);
end;

TTableStore = class(TObject)
  private
    FManyRecords : TObjectList ;
    FTitle2 : Variant;
    FNormalEarn : Double;
  public
    function  GetTitle2 : String;
    function  GetNormalEarn : Double;
    function GetManyRecords: TObjectList;
    procedure SetManyRecords(Value: TObjectList; DoValidation: Boolean = True);
    procedure SetTitle2(Value: String; DoValidation: Boolean = True);
    procedure SetNormalEarn(Value: Double; DoValidation: Boolean = True);
end;

private
  FReportObj : TTableStore;
  FRecord: TRecord;
  objectListTemp: TObjectList;

implementation
  objectListTemp := TObjectList.Create(false);
  FRecord := TRecord.create;

  Frecord.SetDescription…
  Frecord.SetDirect…

  objectListTemp.add(FRecord);

//next...
//(get next record… until eof.)

finally
  FReportObj.SetManyRecords(objectListTemp);

//===================== Retreival

  FReportObj : TTableStore;
  fListOfRecords : TObjectList;
  FCurrentRecord : TRecord;

  fListOfRecords := fReportObj.GetManyRecords;
  fListOfRecords.count // (is ok)
  FCurrentRecord := fListOfRecords.Items[1]     // ?????????

错误是TObjList<> TRecord。我是Delphi的新手,所以这可能很简单。我错过了什么或不理解?感谢。

2 个答案:

答案 0 :(得分:7)

您需要使用以下内容将TObject转换为TRecord:

FCurrentRecord := TRecord(FListOfRecords.Items[1]);

可以反过来这样做,你可以这样做:

var
  X: TRecord;
  Y: TObject;
begin
  X := TRecord.Create;
  Y := X;
end;

这是因为编译器知道TRecord来自TObject,但是在你的代码中,编译器无法知道列表中的TObject实际上是一个TRecord。

我建议使用泛型而不是TObjectList。这将创建您的对象类型的列表。您可以将其用作TRecordList。

type
  TRecordList = TObjectList<TRecord>;

创建它时,您应该使用:

  FManyRecords := TRecordList.Create;

为此,您需要在uses子句中包含System.Generics.Collections。

答案 1 :(得分:1)

有些人建议你使用泛型来解决你的问题,但我认为使用仿制药是没有必要的,因为它们可能会损害你的表现,而不是因为它们会带来很多自己的东西,这会增加你的EXE大小和应用程序内存使用情况。 相反,您可以通过编写索引属性来轻松解决此问题,以便访问内部列表项,如果TObjectList未集成到类中,则可以进行其他操作。 你这样做是这样的:

TRecord = class(TObject)
private
  FDescription : Variant;
  FDirectDeposit : Double;
public
  function  GetDescription : Variant;
  function  GetDirectDeposit : Double;
  procedure SetDescription(Value: Variant; DoValidation: Boolean = True);
  procedure SetDirect(Value: Double; DoValidation: Boolean = True);
end;

TTableStore = class(TObject)
private
  FManyRecords : TObjectList;
protected
  //Used to read record from the internal list which has specific index
  function GetRecord(index: Integer): TRecord;
  //Used to write record on the internal list which has psecific index
  procedure SetRecord(index: Integer; Value: TRecord);
public
  //This property alows you to access any Record from your internal list
  property MyRecord[index: Integer]: TRecord read GetRecord write SetRecord;
  //Used for adding new records to your internal list
  procedure AddRecord(MyRecord: TRecord);
  //Used to remove a record with specific index from your internal list
  procedure RemoveRecord(index: Integer);
end;

implementation

procedure TTableStore.AddRecord(MyRecord: TRecord);
begin
    //We simply call TObjectList.Add method and pass reference to the object
    //we wish to add to the list
    FManyRecords.Add(MyRecord);
end;

function TTableStore.GetRecord(index: Integer): TRecord;
begin
    //We read TObjectList item as we normally would and then we typecast it
    //to TRecord class as this is our expected result.
    result := TRecord(FManyRecords[index]);
end;

procedure TTableStore.RemoveRecord(index: Integer);
begin
    //We simply call TObjectList.delete method passing it a index number of
    //item we wish to remove
    FManyRecords.Delete(index);
end;

procedure TForm4.Button1Click(Sender: TObject);
var MyRecord: TRecord;
    Description: Variant;
begin
    Description := 'Test';
    //We create our record
    MyRecord := TRecord.Create;
    //We set description of our record
    MyRecord.SetDescription(Description);
    //We add our record to the internal table
    MyTableStore.AddRecord(MyRecord);
    //We check to see if record which is stored in out internal table on
    //index 0 to see if its description matches our description variable
    if MyTableStore[0].GetDescription = Description then
    begin
        MessageDlg('It works!',mtInformation,[mbOK],0);
    end;
    //Change description to list record directly
    MyTableStore[0].SetDescription('Test2');
    //Test again to see if description got properly updated
    if MyTableStore[0].GetDescription = 'Test2' then
    begin
        MessageDlg('It works!',mtInformation,[mbOK],0);
    end;
end;

通过这种方式,您可以避免使用任何泛型。 我在上面展示的类似方法可以转发类中任何构建的任何属性或方法(TObjectList实际上是在TTableStore类的类中构建的)