Howdey、私はいくつかのインターフェイスを実装するためにTVirtualInterfaceを使用していますDelphiは - 仮想化されたインタフェース
の基本インターフェイスにTVirtualInterfaceをキャストすることはできません。これらの相互作用は、DB内で見つかるキーを表しています。カスタムのコードジェネレーターでインターフェース定義を生成します。例:
// Base code
IKey = interface
function KeyFields : string;
function KeyValues : Variant;
function GetKeyValue(const aKeyName : string) : Variant;
procedure SetKeyValue(const aKeyName : string; Value : Variant);
end;
// Generated code
ITable1Key = interface(IKey)
end;
ITable1Key1 = interface(ITable1Key)
procedure SetField1(const Value : string);
function GetField1 : string;
property Field1 : string read GetField1 write SetField1;
end;
ITable1Key2 = interface(ITable1Key)
procedure SetField1(const Value : string);
function GetField1 : string;
property Field1 : string read GetField1 write SetField1;
procedure SetField2(const Value : string);
function GetField2 : string;
property Field2 : string read GetField1 write SetField1;
end;
// Other generated declarations
私はTVirtualInterfaceを使用して、1つずつ実装するのではなく、各IKeyインターフェイスを実装します。 TKey.Castは、インターフェイスサポートされていないエラーを返したものの
TKey = TVirtualInterface
public
constructor Create(aType : PTypeInfo);
function Cast : IKey;
end;
TKey<T : IKey>
public
constructor Create; reintroduce;
function Cast : T;
end;
constructor TKey.Create(aType : PTypeInfo)
begin
inherited Create(aType, aHandlerMethod);
end;
function TKey.Cast;
var
pInfo: PTypeInfo;
begin
pInfo := TypeInfo(IKey);
if QueryInterface(GetTypeData(pInfo).Guid, Result) <> 0 then
begin
raise Exception.CreateFmt('Sorry, TKey is unable to cast %s to its interface ', [string(pInfo.Name)]);
end;
end;
constructor TKey<T>.Create;
begin
inherited Create(TypeInfo(T));
end;
function TKey<T>.Cast;
var
pInfo: PTypeInfo;
begin
pInfo := TypeInfo(T);
if QueryInterface(GetTypeData(pInfo).Guid, Result) <> 0 then
begin
raise Exception.CreateFmt('Sorry, TKey<T> is unable to cast %s to its interface ', [string(pInfo.Name)]);
end;
end;
私は、TKey.Cast法を用いたT型にTKEY仮想インターフェイスをキャストする問題がない:私のTVirtualInterfaceに
ものの、。
私はそれを望んでいた方法で働いていなかった部分がSystem.Rttiでチェック:今
function TVirtualInterface.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if iid = FIID then
begin
_AddRef;
Pointer(Obj) := @VTable;
Result := S_OK;
end
else
Result := inherited
end;
を、どのように私は親であるIIDに自分自身をキャストするTVirtualInterfaceを強制することができますFIIDフィールドのインタフェース? IKeyインターフェイスのTVirtualInterfaceの別のインスタンスを作成する必要がありますか?
ありがとうございました。
この「制限」は新しい問題ですか? Delphiでは、継承されたインターフェイスの実装を宣言しなければなりませんでした。ただし、クラスが派生インターフェイスと基本インターフェイスの両方を直接実装したインターフェイス実装は、その基本クラス自体が宣言したベースクラスから継承されますインタフェースの実装。唯一の「問題」は、実際にインタフェース自体の実装を宣言することなく、基本クラスがインタフェースのメソッドを実装した場合でした。私の記憶がトリックをプレイしていない限り(私は現在、テストするためにDelphiを持っていません)。 – Deltics
@Deltics: "*これは制限"新しい問題?* " - それはいつもそこにあった。インタフェースのメソッドの実装は、期待どおりに通常の多態性によって基本クラスから派生クラスに継承できますが、各クラスの内部インタフェーステーブルに表示するには、派生クラス宣言ごとにインタフェースを指定する必要があります。したがって、TObject.GetInterface() (拡張子 'IInterface.QueryInterface()'、 'is'と' as'演算子、 'SysUtils。Supports()'など)はそれを見ることができます。理想的ではなく、C++にはそのような制限はありません。 –