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
问题是你要求容器调用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)