2017-09-28 7 views
0

私は別のクラスのオブジェクトのTObjectList<T>のリストを含むクラスを持っています。 TObjectList <myclass>クラスへのフィールドは保存されません

TMyElementClass = class (TPersistent) 
private 
    .... 
public 
    .... 
end; 

TMyElemContainerClass = class (TPersistent) 
private 
    fElemList: TObjectList<TMyElementClass>; 
    ... 
published 
    ElemList: TObjectList<TMyElementClass> read fElemList write fElemList; 
end; 

var 
    Elements: TMyElemContainerClass; 

は、私は両方のクラス登録:

System.Classes.RegisterClass (TMyElemContainerClass); 
    System.Classes.RegisterClass (TMyElementClass); 

Elementsオブジェクトは、ストリームに「保存」されたときに問題があるが、公表されたフィールドのすべてが正しく保存されているのが、リスト自体は」にISN t。

どういうところが間違っていますか?

+0

TObjectListをで多くのいずれかを参照してください(そして実際に多くがある)の例(むしろリストよりも配列を使用しますが、考え方は同じであるが)ではありませんTPersistentの子孫ですか? – Dsm

+0

実際のコードを表示してください。あなたの例はコンパイルされず、オブジェクトリストを作成しているかどうかはわかりません。たとえば、少なくともコンストラクタが必要です。 – Dsm

+0

あなたの期待は高すぎる –

答えて

2

TObjectListはストリーミング可能なクラスではありません。 publishedプロパティでそれを使用しているだけであっても、ストリーミングシステムがストリーミングシステムを自動的に知っているわけではありません。 DFMストリーミングシステムを使用している場合は、TPersistentから派生するクラスだけがストリーミング可能ですが、TObjectListは配信できません。カスタムストリーミングロジックを実装する必要があります。

は例えば、代わりにTCollectionTCollectionItemを使用するように設計を変更することを検討:

TMyElementClass = class (TCollectionItem) 
private 
    ... 
public 
    ... 
published 
    ... 
end; 

TMyElemCollectionClass = class (TCollection) 
private 
    function GetElem(Index: Integer): TMyElementClass; 
    procedure SetElem(Index: Integer; Value: TMyElementClass); 
public 
    constructor Create; reintroduce; 
    function Add: TMyElementClass; reintroduce; 
    function Insert(Index: Integer): TMyElementClass; reintroduce; 
    property Elements[Index: Integer]: TMyElementClass read GetElem write SetElem; default; 
end; 

TMyElemContainerClass = class (TPersistent) 
private 
    fElemList: TMyElemCollectionClass; 
    procedure SetElemList(Value: TMyElemCollectionClass); 
    ... 
public 
    constructor Create; 
    destructor Destroy; override; 
    ... 
published 
    ElemList: TMyElemCollectionClass read fElemList write SetElemList; 
end; 

... 

constructor TMyElemCollectionClass.Create; 
begin 
    inherited Create(TMyElementClass); 
end; 

function TMyElemCollectionClass.GetElem(Index: Integer): TMyElementClass; 
begin 
    Result := TMyElementClass(inherited GetItem(Index)); 
end; 

procedure TMyElemCollectionClass.SetElem(Index: Integer; Value: TMyElementClass); 
begin 
    inherited SetItem(Index, Value); 
end; 

function TMyElemCollectionClass.Add: TMyElementClass; 
begin 
    Result := TMyElementClass(inherited Add); 
end; 

function TMyElemCollectionClass.Insert(Index: Integer): TMyElementClass; 
begin 
    Result := TMyElementClass(inherited Insert(Index)); 
end; 

constructor TMyElemContainerClass.Create; 
begin 
    inherited; 
    fElemList := TMyElemCollectionClass.Create; 
end; 

destructor TMyElemContainerClass.Destroy; 
begin 
    fElemList.Destroy; 
    inherited; 
end; 

procedure TMyElemContainerClass.SetElemList(Value: TMyElemCollectionClass); 
begin 
    fElemList.Assign(Value); 
end; 
1

レミーはあなたにしようとする一つの道を与えました。

このリストストリーミングを手動で実装する方法もあります。

  1. publishedプロパティ一部の仮想、存在しない、公開プロパティは、inとoutストリーミングされるように宣言します
  2. オーバーライドDefineProperties方法からElemListを削除TComponent
  3. からあなたTMyElemContainerClassを導出する

    あなたが持っているでしょう。あなたはそれをElemListと名付けることさえできます。これは、TObjectListオブジェクトの代わりにDelphiで使用されます。

  4. 上記の仮想プロパティのストリーム指向のリーダーおよびライターのメソッドを実装する場合は、すべてのアイテムを繰り返し処理して読み込み/読み込みする必要があります。

はここからドキュメントも見てみようhttp://docwiki.embarcadero.com/Libraries/Berlin/en/System.Classes.TComponent.DefineProperties

How to use DefineProperties in a custom Class Object for Arrays - Delphi

関連する問題