なぜこれが必要なのですか?たとえば、クラスをシリアル化するときに、このようなニーズに遭遇しました。 基本クラスの子孫クラスに関するすべてのルーチンコードと情報を取り出したいという要望がありました。 まあ、怠は、結局のところ、各子クラスに同じことを処方することです。 だから私は考え直した、多分私はここでジェネリックを台無しにすることができます。
そのため、必要なクラス変数をレコードにラップし、それらにメモリを動的に割り当ててから、ポインターを介して使用できます。 このポインターは、中間の一般化クラスのクラス変数に格納されます。 この一般化されたクラスは、さまざまなクラス数学の新しい一意の基本クラスになります。
クラスの特定のインスタンスからこのようなデータにアクセスするには、一般化クラスのコンストラクターで初期化されるポインターフィールドを追加します。 そして、このポインターを基本クラスのクラスメソッドに渡すには、追加のパラメーターを使用します。 おそらく隠されたClassSelfの代わりに、このパラメーターの値の置換は、中間の汎用クラスのオーバーロードされたメソッドで実行されます。
基本クラスおよび一般化クラスの実装オプション:unit MyStore; interface uses System.Generics.Collections; type TDataBase = class abstract protected type TDataType = class of TDataBase; TDataList = TList<TDataBase>; TDataInfo = array of Integer; PClassVar = ^TClassVar; TClassVar = record cType :TDataType; cObjs :TDataList; cInfo :TDataInfo; end; protected fVar :PClassVar; class function Init(var cVar :PClassVar):Pointer; overload; class procedure Done(var cVar :PClassVar); overload; static; class procedure AddFild( cVar :PClassVar; var Fild); overload; static; public Tag :Integer; procedure Save; constructor Create; virtual; destructor Destroy; override; end; TDataProx<T:class> = class(TDataBase) protected class var cVar :TDataBase.PClassVar; class function Init:T; overload; inline; class procedure Done; overload; inline; class procedure AddFild(var Fild); overload; inline; public constructor Create; overload; override; class function Objs:TList<T>; inline; end; implementation class procedure TDataBase.AddFild(cVar: PClassVar; var Fild);
使用例: unit MyData; interface uses MyStore; type TDataA = class(TDataProx<TDataA>) Data :Integer; Note: string; class constructor Init; class destructor Done; class procedure Work; end; TDataB = class(TDataProx<TDataB>) Data :Double; Memo :array of string; class constructor Init; class destructor Done; end; implementation class destructor TDataA.Done; begin Done; end; class constructor TDataA.Init; begin with Init do begin AddFild(Data); AddFild(Note); end; end; class procedure TDataA.Work; var Obj :TDataA; begin for Obj in Objs do Inc(Obj.Data,Obj.Tag); end; class destructor TDataB.Done; begin Done; end; class constructor TDataB.Init; begin with Init do begin AddFild(Data); AddFild(Memo); end; end; end.