0

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'

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
jmontegrosso
  • 89
  • 1
  • 11
  • 6
    In what context? If `T` is coming from a higher context, ie a Generic class with a `TDictionary` data member, then it should work fine. Can you provide a [mcve] showing what exactly you are having trouble with? – Remy Lebeau Sep 19 '21 at 04:42
  • 2
    If you want to extend generic dictionary class you probably want `TDictionary = class(TDictionary>)` – Dalija Prasnikar Sep 19 '21 at 09:42
  • Or if you want to constrain secondary generic type to `TList` use `TDictionary> = class` – Dalija Prasnikar Sep 19 '21 at 09:44
  • 1
    @jmontegrosso for future reference, such important details belong in your main question, not in comments. I have moved them for you this time. Next time, please be more diligent about asking complete and detailed questions up front. – Remy Lebeau Sep 19 '21 at 18:27

1 Answers1

4

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;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770