【问题标题】:Is it possible in Delphi to declare a TDictionary with a Generic value type?是否可以在 Delphi 中声明具有通用值类型的 TDictionary?
【发布时间】:2021-09-19 01:25:10
【问题描述】:

Delphi 可以做如下声明吗?

TDictionary <T, TList <T>>

编译器不喜欢它:

未声明的标识符:'T'

我在uses子句中添加了:

System.Generics.Collections;

更新:使用这段代码我有这些问题:

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;

我更改了单元代码,但在它起作用之前,我不知道我失败了。

未声明的标识符:'T'

【问题讨论】:

  • 在什么情况下?如果T 来自更高的上下文,即带有TDictionary 数据成员的通用类,那么它应该可以正常工作。您能否提供minimal reproducible example 说明您遇到的具体问题?
  • 如果你想扩展通用字典类你可能想要TDictionary&lt;T&gt; = class(TDictionary&lt;T, TList&lt;T&gt;&gt;)
  • 或者如果你想将第二泛型类型限制为TList&lt;T&gt;,请使用TDictionary&lt;T, V: TList&lt;T&gt;&gt; = class
  • @jmontegrosso 供将来参考,这些重要细节属于您的主要问题,而不是 cmets。这次我为你搬走了它们。下次,请更加勤奋地提前提出完整而详细的问题。

标签: delphi generics tdictionary


【解决方案1】:

您似乎对泛型的工作原理存在根本性的误解。我强烈建议你更小心read the documentation

您正在尝试在需要特定类实例化的上下文中使用TDictionary。在您显示的代码中,编译器是正确的,T 是用于实例化您对 TDictionary 的使用的未知类型。

在您使用T 的任何地方,您都需要指定要与字典一起使用的实际类型,例如:

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; 

否则,您需要将TListado本身声明为具有自己的参数的Generic类,然后您可以使用它来实例化TDictionary,然后您可以在实例化TListado时为该参数指定一个类型,例如:

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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 2020-03-31
    相关资源
    最近更新 更多