如何将变量类型声明为泛型?

时间:2019-12-17 11:13:29

标签: delphi

我正在创建一个双向链接列表类,并且试图更改在创建对象时列表存储的数据类型。

TItem = record
  value: string;
  address, prev, next: integer;
end;

TDoubleLinkedList = class
private
  length, head, tail: integer;
  data: array of TItem;
public
  constructor Create;
  procedure add(value: string);
  function get(address: integer): string;
  property Values[address: integer]: string read get; default;
end;

是否有任何方法可以将TItem.value声明为具有可变类型,而不是在创建对象时可以更改?我希望能够(在一个单独的单元中)调用类似于类型数组的东西,并使TItem.value成为该类型。

2 个答案:

答案 0 :(得分:7)

  

我希望能够(在一个单独的单元中)调用类似于类型数组的东西,并使TItem.value成为该类型。

根据您的实际需求,您可以选择:

  • Generics适用于列表中所有元素都具有相同类型的情况。实际上,System.Generics.Collections
  • 中的标准库中有一些现成的列表实现可供使用。
  • Variant当您需要动态行为时(如JS中),当在代码的不同区域中将同一变量视为整数或字符串时,很好用
  • TValue允许您存储具有不同类型的元素,但是类型安全,即,一旦定义,类型就不会更改。两篇好文章:Introduction to TValueTValue in Depth

答案 1 :(得分:0)

  

是否有任何方法可以将TItem.value声明为具有在创建对象时可以更改的变量类型?

使用泛型进行记录和上课,因此data[x].value的类型绑定到T的类型TDoubleLinkedList

type
  TItem<T> = record
    value: T;
    address, prev, next: integer;
  end;

  TDoubleLinkedList<T> = class
  private
    length, head, tail: integer;
    data: array of TItem<T>;
  public
    constructor Create;
    procedure add(value: T);
    function get(address: integer): T;
    property Values[address: integer]: T read get; default;
  end;

用法示例:

var
  dll_int: TDoubleLinkedList<integer>;
  dll_string: TDoubleLinkedList<string>;
begin
  dll_int := TDoubleLinkedList<integer>.Create;
  try
    dll_int.add(42);
    writeln(dll_int.get(0)); // returns 42
  finally
    dll_int.Free;
  end;

  dll_string := TDoubleLinkedList<string>.Create;
  try
    dll_string.add('Test');
    writeln(dll_string.get(0)); // returns 'Test'
  finally
    dll_string.Free;
  end;

end.