Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi:如何使用TObjectList<;T>;?_Delphi_Generics_Tobjectlist - Fatal编程技术网

Delphi:如何使用TObjectList<;T>;?

Delphi:如何使用TObjectList<;T>;?,delphi,generics,tobjectlist,Delphi,Generics,Tobjectlist,我需要了解如何使用通用的Delphi2009TObjectList。我的非TObjectList尝试看起来像 TSomeClass = class(TObject) private FList1: Array of TList1; FList2: Array of TList2; public procedure FillArray(var List: Array of TList1; Source: TSource); Overload; procedure FillArray

我需要了解如何使用通用的Delphi2009
TObjectList
。我的非
TObjectList
尝试看起来像

TSomeClass = class(TObject)
private
  FList1: Array of TList1;
  FList2: Array of TList2;
public
  procedure FillArray(var List: Array of TList1; Source: TSource); Overload;
  procedure FillArray(var List: Array of TList2; Source: TSource); Overload;
end;
这里,
TList1
TList2
继承了相同的构造函数
constructor TParent.Create(键:string;值:string)。但是,由于不同的专业化(例如不同的私有领域),它们将不是同一类型。因此,我必须编写两种几乎相同的填充方法:

procedure TSomeClass.FillArray(var List: Array of TList1; Source: TSource);
begin
  for i := 0 to Source.List1.Count - 1 do begin
    SetLength(List, Length(List) + 1);
    List[i] := TList1.Create(Source.List1[i].Key, Source.List1[i].Value);
  end;
end;

使用
FillArray(列表:TList2的数组;源:TSource)完全相同,除了用
TList2
替换
TList1
。据我所知,这可以通过使用
TObjectList
和单一填充方法巧妙地避免;然而,我不知道该怎么做。有人对此有什么好的建议吗?谢谢

上的官方Embarcadero文档Wiki包含一个简单的代码示例

我不确定问题的确切含义,但为了解决TObjectList的广泛使用,TObjectList的示例初始化代码可能如下所示:

var
  List: TObjectList<TNewObject>;
  Obj: TNewObject;
begin
  { Create a new List. }
  List := TObjectList<TNewObject>.Create();

  { Add some items to the List. }
  List.Add(TNewObject.Create('One'));
  List.Add(TNewObject.Create('Two'));

  { Add a new item, but keep the reference. }
  Obj := TNewObject.Create('Three');
  List.Add(Obj);
var
列表:TObjectList;
对象:TNewObject;
开始
{创建一个新列表。}
List:=TObjectList.Create();
{将一些项目添加到列表。}
List.Add(TNewObject.Create('One'));
List.Add(TNewObject.Create('Two');
{添加新项,但保留引用。}
Obj:=TNewObject.Create('Three');
列表。添加(Obj);
应该可以让您了解TObjectList可以做什么,但是如果我正确理解了这个问题,您似乎希望能够向的单个实例添加多个类类型?TObjectList只能使用一种类型启动,因此如果您使用一个接口或抽象类启动TObjectList,并且该接口或抽象类由您希望添加到其中的所有类共享,则可能会更好


与创建自己的对象相比,使用属性的一个重要区别是属性的存在性,它会告诉属性是否拥有您添加到其中的对象,因此它是否应该自行管理释放对象。

使用通用列表无法将其压缩,因为泛型的类型是类定义的一部分。因此,
TObjectList
TObjectList
不同(且不兼容)。与普通的TList/TObjectList相比,使用泛型列表的主要好处是提高了类型安全性,减少了强制转换,代码更干净

另外,如果您使用的是键/值对,是否将它们放入列表中,然后通过搜索键并返回关联的值来检索它们?如果是这样,请查看Generics.Collections中的TDictionary。它是一个通用的键/值哈希表,将大大简化此过程。

类似的内容

TSomeClass = class
private
  FList1: TArray<TList1>;
  FList2: TArray<TList2>;
public
  procedure FillArray<T>(var List: TArray<T>; Source: TSource);
end;

procedure TSomeClass.FillArray<T>(var List: TArray<T>; Source: TSource);
begin
  for i := 0 to Source.List1.Count - 1 do begin
    SetLength(List, Length(List) + 1);
    List[i] := T.Create(Source.List1[i].Key, Source.List1[i].Value);
  end;
end;
TSomeClass=class
私有的
飞行物1:柏油;
飞行物2:柏油;
公众的
过程填充数组(变量列表:TArray;源:TSource);
结束;
过程TSomeClass.FillArray(变量列表:TArray;源:TSource);
开始
对于i:=0到Source.List1.Count-1,开始
设置长度(列表,长度(列表)+1);
List[i]:=T.Create(Source.List1[i].Key,Source.List1[i].Value);
结束;
结束;

afaict,这个或类似的东西应该可以满足您的需要。

1。对于类名2来说,TClass是一个非常糟糕的选择。列表未在FillChar3中声明为var。设置长度(列表,长度(列表));事实上什么都没有。我们:是的,这真是个坏名字。编辑了此建议和其他建议。:)谢谢梅森。这回答了我的问题。嗨,杰米。我看过你提到的例子。不幸的是,它没有我想要的那么详细,留下了很多没有说的。具体来说,我想用几乎相同的代码填写两个不同的列表。然而,正如梅森指出的那样,这是不可能做到的。所以,我来了!啊,我想是的,这就是为什么我说ObjectList只能用一个类型启动,所以如果可能的话,您必须修改类来派生接口或基类,以使其工作。