将TObjectList作为参数传递-Delphi Xe2

将TObjectList作为参数传递-Delphi Xe2,delphi,delphi-xe2,Delphi,Delphi Xe2,我有一个“Form1”,它通过参数将对象列表发送到“Form2”。但是Delphi将该列表作为参考发送,因此如果我关闭“表1”列表,则“表2”中会出现错误 作为示例: 表格1: var list: TObjectList<TPerson>; begin list := TObjectList<TPerson>.Create(); Try list.Add(TPerson.Create('JOHN', 29));

我有一个“Form1”,它通过参数将对象列表发送到“Form2”。但是Delphi将该列表作为参考发送,因此如果我关闭“表1”列表,则“表2”中会出现错误

作为示例:

表格1:

var list: TObjectList<TPerson>;
    begin

      list  :=  TObjectList<TPerson>.Create();

      Try

      list.Add(TPerson.Create('JOHN', 29));
      list.Add(TPerson.Create('MARK', 27));

      Form2.getList(list);


      Finally
       FreeAndNil(list);
      End;
var列表:TObjectList;
开始
list:=TObjectList.Create();
尝试
添加(TPerson.Create('JOHN',29));
添加(TPerson.Create('MARK',27));
表2.获取列表(列表);
最后
FreeAndNil(列表);
结束;
问题是,在“Form1”中释放列表后,引用指向已释放的对象

问题是:

如何将列表作为副本而不是参考发送到“表格2”


谢谢

Form2需要获得列表的所有权,而不是让Form1释放列表,或者通过列表循环将内容复制到自己的本地列表。

Form2需要获得列表的所有权,而不是让Form1释放列表,或者在列表中循环,将内容复制到它自己的本地列表。

检查
Tobjectlist
的所有权,如果您释放列表并且列表拥有对象,则在释放列表时它将释放列表中的对象


尝试
TObjectList.Create(false)

检查
Tobjectlist
的所有权,如果您释放列表并且列表拥有对象,则在释放列表时,列表将释放列表中的对象


尝试
TObjectList.Create(false)

考虑到问题的确切表述方式,答案是“不可能的”,因为TObjectList是一个类,而Delphi中的类是引用类型

事实上,传递给方法Form2.getList()的是一个值,但该值是一个引用,因此其工作原理非常类似于通过引用传递值

如果您需要列表的副本,您必须自己创建,但是,变量list引用了一个拥有这些项的列表,因此即使您在Form2中创建了第二个列表,并且只需添加列表中作为参数接收到的那些项,在表单1中销毁列表时,项目将继续销毁

在您的位置,我将实现我的表单2。getList将项目从表单1中的列表移动到表单2中的列表。大概是这样的:

procedure TForm2.getList(aPeople: TObjectList<TPerson>);
begin
  while aPeople.Count>0 do
    FPeople.Add(aPeople.Extract(aPeople[0]));
end;
过程TForm2.getList(aPeople:TObjectList);
开始
当aPeople.Count>0时
FPeople.Add(aPeople.Extract(aPeople[0]);
结束;

在此代码中,FPeopleTForm2的数据成员,声明为TObjectListExtract方法从列表中删除项目,而不释放它。因此,提取后,该项将添加到内部列表中。因为它不再在外部列表中,所以当列表被释放时,它将不会被释放。

考虑到问题的确切表述方式,答案是“不可能的”,因为TObjectList是一个类,而Delphi中的类是引用类型

事实上,传递给方法Form2.getList()的是一个值,但该值是一个引用,因此其工作原理非常类似于通过引用传递值

如果您需要列表的副本,您必须自己创建,但是,变量list引用了一个拥有这些项的列表,因此即使您在Form2中创建了第二个列表,并且只需添加列表中作为参数接收到的那些项,在表单1中销毁列表时,项目将继续销毁

在您的位置,我将实现我的表单2。getList将项目从表单1中的列表移动到表单2中的列表。大概是这样的:

procedure TForm2.getList(aPeople: TObjectList<TPerson>);
begin
  while aPeople.Count>0 do
    FPeople.Add(aPeople.Extract(aPeople[0]));
end;
过程TForm2.getList(aPeople:TObjectList);
开始
当aPeople.Count>0时
FPeople.Add(aPeople.Extract(aPeople[0]);
结束;

在此代码中,FPeopleTForm2的数据成员,声明为TObjectListExtract方法从列表中删除项目,而不释放它。因此,提取后,该项将添加到内部列表中。因为它不再在外部列表中,所以当列表被释放时,它将不会被释放。

我认为将变量移到Form1范围之上可能是另一种选择。我认为将变量移到Form1范围之上可能是另一种选择。比你想象的更难。步骤1是将TPerson转换为值类型,即记录。一旦你完成了这项工作,列表复制就变成了一行程序。比你想象的要难。步骤1是将TPerson转换为值类型,即记录。一旦你完成了,列表复制就变成了一行。确切地说,你完全理解我的位置。我已经写了像你一样的代码,它可以工作了!但我想知道是否有可能创建一个列表副本而不循环所有项目。我相信不是。确切地说,你完全理解我的处境。我已经写了像你一样的代码,它可以工作了!但我想知道是否有可能创建一个列表副本而不循环所有项目。我相信没有。