如何在Delphi中调用TObjectDictionary的继承构造函数

Del*_*der 1 delphi generics constructor inherited

在阅读了 TDictionary 相对于 TStringList 的显着性能改进后,我创建了以下类:

    TAnsiStringList = class(TObjectDictionary<AnsiString,TObject>)
    public
      constructor Create(const OwnsObjects: Boolean = True); reintroduce;
      destructor Destroy; override;
      procedure Add(const AString: AnsiString);
      procedure AddObject(const AString: AnsiString; AObject: TObject);
    end;
Run Code Online (Sandbox Code Playgroud)

我这样编写构造函数:

  { TAnsiStringList }

    constructor TAnsiStringList.Create(const OwnsObjects: Boolean = True);
    begin
      if OwnsObjects then
        inherited Create([doOwnsKeys,doOwnsValues])
      else
        inherited Create;
    end;
Run Code Online (Sandbox Code Playgroud)

...期望将调用此 TObjectDictionary 构造函数:

    constructor Create(Ownerships: TDictionaryOwnerships; ACapacity: Integer = 0); overload;
Run Code Online (Sandbox Code Playgroud)

...如果指定了 Ownerships 参数。如果未指定 Ownerships 参数,我预计将调用以下继承的 TDictionary 构造函数:

    constructor Create(ACapacity: Integer = 0); overload;
Run Code Online (Sandbox Code Playgroud)

代码编译并运行,但是当我调用时

    inherited Create([doOwnsKeys,doOwnsValues]) I get the following error:
Run Code Online (Sandbox Code Playgroud)

无效的类类型转换

有谁看到我做错了什么,有没有正确的方法来做到这一点?

TIA

Dav*_*nan 5

问题是你要求容器调用Free问题是,当物品被移除时,但您的密钥不是类,因此这是一个无效的请求。这是在运行时而不是编译时捕获的,因为所有权直到运行时才确定。

您只想doOwnsValues并且应该删除doOwnsKeys.

 if OwnsObjects then
    inherited Create([doOwnsValues])
 else
   inherited Create;
Run Code Online (Sandbox Code Playgroud)

就其价值而言,如果您试图制作AnsiString相当于 的内容TStringList,那么您的方法就有缺陷。字符串列表是一个有序的容器,但字典不是。您将无法按整数索引、按顺序迭代等等。我也不明白为什么您要强制此类的所有使用者将对象声明为类型TObject。您应该将该参数保留为自由,以便消费者指定。这就是泛型的美妙之处。

也许您不需要有序的容器,在这种情况下您需要字典。但在这种情况下,您根本不需要创建一个新类。你可以简单地使用TObjectDictionary原样使用。

如果您执意要创建子类,那么我会这样做:

type
  TAnsiStringDict<T: class> = class(TObjectDictionary<AnsiString, T>)
Run Code Online (Sandbox Code Playgroud)

这将允许类的使用者决定将哪种类型的对象放入字典中,并维护编译时类型安全。

因此,当您需要列表框的字典时,您可以声明一个如下变量:

var
  ListBoxDict: TAnsiStringDict<TListBox>;
Run Code Online (Sandbox Code Playgroud)