charlieb
charlieb

Reputation: 85

How to declare variable type as generic?

I am creating a double linked list class and I am trying to change the type of data that the list is storing when the object is created.

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;

Is there any way to declare TItem.value as having a variable type than can be changed when the object is created? I want to be able to (in a separate unit) call something analogous to array of type and have TItem.value be that type.

Upvotes: 1

Views: 417

Answers (2)

DelphiCoder
DelphiCoder

Reputation: 2007

Is there any way to declare TItem.value as having a variable type that can be changed when the object is created?

Make your record and class using generics, so the type of data[x].value is bound to the type T of the 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;

Example usage:

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.

Upvotes: 0

Torbins
Torbins

Reputation: 2216

I want to be able to (in a separate unit) call something analogous to array of type and have TItem.value be that type.

Depending on your real needs, you may choose from:

  • Generics are good for cases, when all elements in the list will have the same type. In fact there are some ready to use list implementations in standard library in System.Generics.Collections
  • Variant is nice when you need dynamic behaviour, as in JS, when the same variable can be treated as integer or string in different areas in your code
  • TValue allows you to store elements with different types, but is type safe, i.e. once defined, type does not change. Two good articles: Introduction to TValue, TValue in Depth

Upvotes: 7

Related Questions