【问题标题】:Delphi: how to use TObjectList<T>?Delphi:如何使用 TObjectList<T>?
【发布时间】:2009-11-03 01:42:43
【问题描述】:

我需要了解如何使用通用的 Delphi 2009 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;

这里,TList1TList2 继承了相同的构造函数 constructor TParent.Create(Key: string; Value: 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(List: Array of TList2; Source: TSource); 相同,除了将TList1 替换为TList2。据我了解,这可以通过使用TObjectList 和单一填充方法巧妙地规避;但是,我不知道该怎么做。有人对此有一些好的建议吗?谢谢!

【问题讨论】:

  • 1. TClass 是一个非常糟糕的类名选择 2. List 在 FillChar 中没有声明为 var
  • 3.设置长度(列表,长度(列表));实际上什么都不做
  • Uwe:是的,这是一个非常糟糕的名字。编辑了这个和其他建议。 :)

标签: delphi generics tobjectlist


【解决方案1】:

您无法使用泛型列表将其浓缩,因为泛型的类型是类定义的一部分。所以TObjectList&lt;TMyClass1&gt;TObjectList&lt;TMyClass2&gt; 不同(并且不兼容)。与普通 TList/TObjectList 相比,使用泛型列表的主要好处是提高了类型安全性,减少了类型转换和更简洁的代码。

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

【讨论】:

  • 谢谢梅森。这回答了我的问题。
【解决方案2】:

Generics.Collections.TObjectList 上的 Embarcadero 官方文档 Wiki 包含 TObjectList in action 的简单代码示例。

我不确定这个问题到底是什么,但为了解决 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);

example code 应该让您了解 TObjectList 可以做什么,但是如果我正确理解了这个问题,您似乎希望能够将多个类类型添加到 @ 的单个实例中987654324@? TObjectList 只能使用单一类型启动,因此如果您使用接口或抽象类启动 TObjectList 可能会更好,该接口或抽象类由您希望添加到其中的所有类共享。

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

【讨论】:

  • 嗨,杰米。我看过你说的例子。不幸的是,它没有我想的那么详细,还有很多没有说的。具体来说,我想使用几乎相同的代码填充两个不同的列表。然而,正如梅森指出的那样,这是不可能的。所以Overload-bonanza,我来了!
  • 啊,我是这么认为的,这就是为什么我说 ObjectList 只能使用单一类型启动,所以如果可能的话,您必须修改类以派生接口或基类,以便完成这项工作。
【解决方案3】:

这样的?

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;

这个,或者类似的东西应该做你想做的,afaict。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多