我需要一個多態對象(不同的對象類,但具有一個公共基類)的列表,我可以'持久'作爲表單文件的一部分。德爾福中的持久性多態性列表
TList不是持久的,並且TCollection不是多態的。
我可以推出自己的產品,但不想重新發明輪子。想法?
我需要一個多態對象(不同的對象類,但具有一個公共基類)的列表,我可以'持久'作爲表單文件的一部分。德爾福中的持久性多態性列表
TList不是持久的,並且TCollection不是多態的。
我可以推出自己的產品,但不想重新發明輪子。想法?
沒有任何標準庫類可以滿足您的需求。你需要推出自己的,或找到第三方庫。
我認爲這是你問的問題的答案。如果你想要圖書館的建議,這是關閉的話題,因爲我確信像你這樣的高級代表用戶都知道。 –
謝謝。我試圖避免在購物清單問題的陰暗水域中出現這種結局。我當然不會特別要求圖書館,但如果這是答案...... – Roddy
我認爲是。據我所知,標準庫中沒有任何可以開箱即可保存異構集合的集合。 –
我不確定TCollection爲什麼不能擁有TCats和TDogs?
TAnimal = class(TCollectionItem)
end;
TCat = class(TAnimal)
end;
TDog = class(TAnimal)
end;
FCollection : TCollection;
FCollection := TCollection.Create(TAnimal);
cat : TCat
cat := TCat.Create(FCollection);
dog : TDog
dog := TDag.Create(FCollection);
var
i : integer;
begin
for I := 0 to FCollection.Count - 1 do
TAnimal(FCollection.Items[i]).DoSomething;
end;
FCollection現在將舉辦2項,一隻貓和一隻狗
或者我在這裏錯過了點?
對於使用默認流式框架,您必須創建包裝器集合項目,該項目可以保存並創建不同類別的對象實例。
unit PolyU;
interface
uses
System.SysUtils,
System.Classes;
type
TWrapperItem = class(TCollectionItem)
protected
FObjClassName: string;
FObjClass: TPersistentClass;
FObj: TPersistent;
procedure SetObjClass(Value: TPersistentClass);
procedure SetObjClassName(Value: string);
procedure SetObj(Value: TPersistent);
function CreateObject(OClass: TPersistentClass): Boolean; dynamic;
public
property ObjClass: TPersistentClass read FObjClass write SetObjClass;
published
// ObjClassName must be published before Obj to trigger CreateObject
property ObjClassName: string read FObjClassName write SetObjClassName;
property Obj: TPersistent read FObj write SetObj;
end;
implementation
procedure TWrapperItem.SetObjClass(Value: TPersistentClass);
begin
if Value <> FObjClass then
begin
FObj := nil;
FObjClass := Value;
if Value = nil then FObjClassName := ''
else FObjClassName := Value.ClassName;
CreateObject(FObjClass);
end;
end;
procedure TWrapperItem.SetObjClassName(Value: string);
begin
if Value <> FObjClassName then
begin
FObj := nil;
FObjClassName := Value;
if Value = '' then FObjClass := nil
else FObjClass := FindClass(Value);
CreateObject(FObjClass);
end;
end;
procedure TWrapperItem.SetObj(Value: TPersistent);
begin
FObj := Value;
if Assigned(Value) then
begin
FObjClassName := Value.ClassName;
FObjClass := TPersistentClass(Value.ClassType);
end
else
begin
FObjClassName := '';
FObjClass := nil;
end;
end;
function TWrapperItem.CreateObject(OClass: TPersistentClass): Boolean;
begin
Result := false;
if OClass = nil then exit;
try
FreeAndNil(FObj);
if OClass.InheritsFrom(TCollectionItem) then FObj := TCollectionItem(TCollectionItemClass(OClass).Create(nil))
else
if OClass.InheritsFrom(TComponent) then FObj := TComponentClass(OClass).Create(nil)
else
if OClass.InheritsFrom(TPersistent) then FObj := TPersistentClass(OClass).Create;
Result := true;
except
end;
end;
end.
類是打算由TWrapperItem
包裹必須通過RegisterClass
或RegisterClasses
方法用Delphi流媒體系統註冊。
以下測試組件包含可通過IDE進行編輯和流式傳輸的基本集合。對於更多的控制,你可能想編寫自定義的IDE編輯器,但這是從頭開始的基礎。
unit Unit1;
interface
uses
System.Classes,
PolyU;
type
TFoo = class(TPersistent)
protected
FFoo: string;
published
property Foo: string read FFoo write FFoo;
end;
TBar = class(TPersistent)
protected
FBar: integer;
published
property Bar: integer read FBar write FBar;
end;
TTestComponent = class(TComponent)
protected
FList: TOwnedCollection;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property List: TOwnedCollection read FList write FList;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Test', [TTestComponent]);
end;
constructor TTestComponent.Create(AOwner: TComponent);
begin
inherited;
FList := TOwnedCollection.Create(Self, TWrapperItem);
end;
destructor TTestComponent.Destroy;
begin
Flist.Free;
inherited;
end;
initialization
RegisterClasses([TFoo, TBar]);
finalization
UnRegisterClasses([TFoo, TBar]);
end.
這是怎麼流傳輸TTestComponent
(如表的一部分)可以看起來像:
object TestComponent1: TTestComponent
List = <
item
ObjClassName = 'TFoo'
Obj.Foo = 'abc'
end
item
ObjClassName = 'TBar'
Obj.Bar = 5
end>
Left = 288
Top = 16
end
雖然您可能會試圖在TWrapperItem中使用泛型,但它不起作用,因爲[Delphi流式處理系統無法識別泛型類型的已發佈屬性](http://qc.embarcadero.com/wc/qcmain.aspx?d= 103296) –
在何種意義上是'TCollection'不是多態? –
@DavidHeffernan:'Add'和'insert'方法總是創建相同類型的TCollectionItem,當然? – Roddy
@DavidHeffernan,我說他們總是創建您在構造函數中傳遞給TCollection的類類型。你不能擁有一個包含TDog和TCats的TAnimals TCollection。 (警告:錯誤的OO示例!)http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Classes_TCollection_Create.html – Roddy