在阅读了 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;
我这样编写构造函数:
{ TAnsiStringList }
constructor TAnsiStringList.Create(const OwnsObjects: Boolean = True);
begin
if OwnsObjects then
inherited Create([doOwnsKeys,doOwnsValues])
else
inherited Create;
end;
...期望这个 TObjectDictionary 构造函数将被调用:
constructor Create(Ownerships: TDictionaryOwnerships; ACapacity: Integer = 0); overload;
...如果指定了 Ownerships 参数。如果没有指定 Ownerships 参数,我预计会调用以下继承的 TDictionary 构造函数:
constructor Create(ACapacity: Integer = 0); overload;
代码编译并运行,但是当我调用
inherited Create([doOwnsKeys,doOwnsValues]) I get the following error:
无效的类类型转换
有谁看到我做错了什么,有没有合适的方法来做到这一点?
TIA
最佳答案
问题是您要求容器调用 Free
当元素被移除时,在您的 key 上。但是您的 key 不是类,因此这是一个无效请求。这是在运行时而不是编译时捕获的,因为直到运行时才确定所有权。
你只想要doOwnsValues
并且应该删除 doOwnsKeys
.
if OwnsObjects then
inherited Create([doOwnsValues])
else
inherited Create;
对于它的值(value),如果你想制作一个
AnsiString
相当于 TStringList
,那么你的方法是有缺陷的。字符串列表是有序容器,但字典不是。您将无法按整数索引、按顺序迭代等等。我也不明白为什么要强制此类的所有使用者将对象声明为 TObject
类型。 .您应该将该参数留给消费者指定。这就是泛型的美妙之处。也许你不想要一个有序的容器,在这种情况下你需要一本字典。但在这种情况下,您根本不需要创建新类。您可以简单地使用
TObjectDictionary
照原样。如果您对创建子类一无所知,那么我会这样做:
type
TAnsiStringDict<T: class> = class(TObjectDictionary<AnsiString, T>)
这将允许类的使用者决定他们将哪种类型的对象放入字典中,并保持编译时类型安全。
所以,当你想要一个列表框的字典时,你可以声明一个像这样的变量:
var
ListBoxDict: TAnsiStringDict<TListBox>;
关于delphi - 如何在Delphi中调用TObjectDictionary的继承构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15973806/