Home > Net >  Is it possible in Delphi to declare a TDictionary with a Generic value type?
Is it possible in Delphi to declare a TDictionary with a Generic value type?

Time:09-22

Can Delphi make the following statement?

TDictionary <T, TList <T>>

The compiler doesn't like it:

Undeclared identifier: 'T'

I have added in the uses clause:

System.Generics.Collections;

UPDATE: With this code I have these problems:

interface

uses
  System.Generics.Collections;

type
  TListado = class(TObject)
  private
    FListado: TDictionary<T, V: TList<T>>;
    function GetListado: TDictionary<T,TList<T>>;
    procedure SetListado(const Value: TDictionary<T, TList<T>>);
  public
    property Listado: TDictionary<T,TList<T>> read GetListado write SetListado;
    function ReadItems(Cliente: T):TList<T>;
  end;

I changed the unit code but before it worked, I don't know what I'm failing in.

Undeclared identifier: 'T'

CodePudding user response:

You seem to have a fundamental misunderstanding of how Generics work. I strongly suggest you read the documentation more carefully.

You are trying to use TDictionary in contexts where specific instantiations of the class are needed. In the code you have shown, the compiler is correct that T is an unknown type with which to instantiate your use of TDictionary.

Everywhere you are using T, you need to specify an actual type that you want to use with the dictionary, for example:

interface

uses
  System.Generics.Collections;

type
  TListado = class(TObject)
  private
    FListado: TDictionary<Integer, TList<Integer>>;
    function GetListado: TDictionary<Integer, TList<Integer>>;
    procedure SetListado(const Value: TDictionary<Integer, TList<Integer>>);
  public
    property Listado: TDictionary<Integer, TList<Integer>> read GetListado write SetListado;
    function ReadItems(Cliente: Integer): TList<TInteger>;
  end; 

Otherwise, you will need to declare TListado itself as a Generic class with its own parameter, which you can then use to instantiate TDictionary, and then you can specify a type for that parameter when instantiating TListado, eg:

interface

uses
  System.Generics.Collections;

type
  TListado<T> = class(TObject)
  private
    FListado: TDictionary<T, TList<T>>;
    function GetListado: TDictionary<T, TList<T>>;
    procedure SetListado(const Value: TDictionary<T, TList<T>>);
  public
    property Listado: TDictionary<T, TList<T>> read GetListado write SetListado;
    function ReadItems(Cliente: T): TList<T>;
  end; 
var
  list: TListado<Integer>;
begin
  list := TListado<Integer>.Create;
  ...
  list.Free;
end;
  • Related