データセット内のレコードを Delphi のプレジェネリック バージョンの Delphi レコードに変換するインターフェイスを実装しようとしています。現時点ではインターフェイスが好きではありません.可能な限り避けたいサポートへの呼び出しが常に必要であり、私が見逃しているより良い方法があるかどうか疑問に思っていました.
これまでのところ、ナビゲーション インターフェイスとデータ取得インターフェイスが定義されています。
IBaseRecordCollection = interface
procedure First;
procedure Next;
function BOF: boolean;
... // other dataset nav stuff
end;
IRecARecordCollection = interface
function GetRec: TRecA;
end;
IRecBRecordCollection = interface
function GetRec: TRecB;
end;
基本的に、プライベート データセットを含む具体的な基本クラスがあり、IBaseRecordCollection
RecordCollection インターフェイスごとに具象クラスが実装されています。これは、レコード取得ルーチンの実装を使用してIBaseRecordCollection
(プロパティによって処理される) を実装する抽象クラスから派生します。implements
TAbstractTypedRecordCollection = class(TInterfacedObject, IBaseRecordCollection)
private
FCollection: IBaseRecordCollection;
protected
property Collection: IBaseRecordCollection read FCollection implements IBaseRecordCollection;
public
constructor Create(aRecordCollection: IBaseRecordCollection);
end;
TRec1RecordCollection = class(TAbstractTypedRecordCollection, IRecARecordCollection);
public
function GetRec: TRecA;
end;
IRecARecordCollection
さて、これを使用するには、 a を返してから をいじるビルダーを用意する必要がありますSupports
。
すなわち
procedure GetMyRecASet;
var
lRecARecordCollection: IRecARecordCollection;
lRecordCollection: IBaseRecordCollection;
begin
lRecARecordCollection := BuildRecACollection;
if not supports(lRecARecordCollection, IBaseRecordCollection, lRecordCollection) then
raise exception.create();
while not lRecordCollection.EOF do
begin
lRecARecordCollection.GetRec.DoStuff;
lRecordCollection.Next;
end;
end;
これはうまくいきますが、私は呼び出しに熱心ではなく、supports
このように lRecordCollections と lRecARecordCollections を混合します。私はもともと次のようなことができることを望んでいました:
IBaseRecordCollection = interface
// DBNav stuff
end;
IRecARecordCollection = interface (IBaseRecordCollection)
function GetRec: TRecA;
end;
TRec1RecordCollection = class(TInterfacedObject, IRecARecordCollection)
private
FCollection: IBaseRecordCollection;
protected
property Collection: IBaseRecordCollection read FCollection implements IBaseRecordCollection;
public
function GetRec: TRecA;
end;
IBaseRecordCollection
しかし残念なことに、Delphi は IRecARecordCollection の実装がCollection プロパティのimplements
呼び出しと TRec1RecordCollection オブジェクトのベースで分割されていることに気付くほど賢くありませんでした。
これを実現するためのより適切な方法について他に提案はありますか?
-- @David の回答に対して、コメントよりも (長い) 返信をするように編集します。
提案された解決策:
IBaseRecordCollection = interface ['{C910BD0A-26F4-4682-BC82-605C4C8F9173}']
function GetRecNo: integer;
function GetRecCount: integer;
function GetFieldList: TFieldList;
function EOF: boolean;
function BOF: boolean;
...
end;
IRec1RecordCollection = interface (IBaseRecordCollection) ['{E12F9F6D-6D57-4C7D-AB87-8DD50D35DCA2}']
function GetRec: TRec1;
property Rec: TRec1 read GetRec;
end;
TAbstractTypedRecordCollection = class(TInterfacedObject, IBaseRecordCollection)
private
FCollection: IBaseRecordCollection;
protected
property Collection: IBaseRecordCollection read FCollection implements IBaseRecordCollection;
public
constructor Create(aRecordCollection: IBaseRecordCollection);
end;
TRec1RecordCollection = class(TAbstractTypedRecordCollection, IRec1RecordCollection, IBaseRecordCollection)
private
function GetRec: TRec1;
public
property Rec: TRec1 read GetRec;
end;
コンパイルしていません。TRec1RecordCollection
に関連するメソッドが見つからないと不平を言っていますIBaseRecordCollection
。Collection
また、プロパティを Abstract から移動して、すべて同じ結果でRec1RecordCollection
プロパティを再宣言しようとしましたTRec1RecordCollection
もう少し深く見てみると、実装するクラスの直接継承は機能するように見えますIBaseRecordCollection
が、Delphi は を使用してプロパティを介して間接的に継承することを処理できませんimplements
。