我在同一个TOwnedCollection
中添加自己的TCollectionItem
类(继承自TCollectionItem
)时遇到问题。
我参考了Indy的IdMessageParts.pas
作为TIdMessagePart
的推荐。所以我一定是错过了什么,因为我得到了一个“无效的类类型”错误时,添加TMyItem2
。
我希望MyItems: TOwnedCollection
能够存储TMyItem
、TMyItem2
、TMyItem3
。但是在添加TMyItem2
和TMyItem3
时,我收到了“Invalid typecast”错误(仅可接受TMyItem
)。
我错过什么了吗?
TMyItem = class(TCollectionItem)
private
FLabelName: string;
public
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
published
property LabelName: string read FLabelName write FLabelName;
end;
TMyItem2 = class(TMyItem)
private
FCaption: string;
published
property Caption: string read FCaption write FCaption;
end;
TMyItem3 = class(TMyItem)
private
FCaption3: string;
published
property Caption3: string read FCaption3 write FCaption3;
end;
TMyItems = class(TOwnedCollection)
private
function GetMyItem(aIndex: Integer): TMyItem;
protected
constructor Create(aOwner: TAsapListview);
function GetOwner: TPersistent; override;
public
function Add: TMyItem;
function IndexOf(aFieldName: string): Integer;
function MyItemByFieldName(aFieldName: string): TMyItem;
property Items[aIndex: Integer]: TMyItem read GetMyItem; default;
end;
// NOTE: in idMessageParts.pas the add is defined this way
// which I don't quite understand
{
function TIdMessageParts.Add: TIdMessagePart;
begin
// This helps prevent TIdMessagePart from being added
Result := nil;
end;
}
// this is the calling code
with MyItems.Add do
begin
LabelName := 'test'; // works
end;
// Error of invalid typecast occurred here
with MyItems.Add as TMyItem2 do // typecast error here
begin
LabelName := 'label item2';
Caption := 'caption item2';
end;
with MyItems.Add as TMyItem3 do // typecast error here
begin
LabelName := 'label item2';
Caption := 'caption item2';
Caption3 := 'caption3 item2';
end;
1条答案
按热度按时间hmtdttj41#
继承的
TCollection.Add()
方法创建了TCollection
构造函数中指定的类类型的示例,所以Add()
在处理多个TCollectionItem
派生的类时是无用的,因为你不能用这种方法添加多个类。此代码:
因为您告诉
TMyItems
它的项目类别类型是TMyItem
,所以Add()
会建立TMyItem
。此代码:
失败的原因是相同的。你告诉
TMyItems
创建TMyItem
对象,所以你不能把它们转换成你的其他类类型。Indy的
TIdMessageParts
集合覆盖了Add()
,以阻止用户以这种方式使用Add()
。要完成您想要的(以及Indy所做的),您需要调用
TCollectionItem
构造函数,而不是使用Add()
,例如: