Ist es möglich, einen generischen Parameter zu haben, um die Schnittstelle zu definieren, die eine Klasse implementiert?
Oder hat jemand eine Erklärung, warum Delphi dies nicht zulässt (Oder mache ich es einfach falsch?):Generischer Parameter zum Definieren der Schnittstelle, die die generische Klasse implementiert
TInterfacedMyWrapper<T: IInterface> = class(TMyWrapper, T)
function PropGetIntf(): T;
property Intf: T read PropGetIntf implements T;
end;
Das folgende Fehler ergibt:
E2205: Interface type required
E2259: Implements clause only allowed for properties of class or interface type
Dies ist meine Abhilfe:
TInterfacedMyWrapper<T: IInterface> = class(TMyWrapper)
function PropGetIntf(): T;
property Intf: T read PropGetIntf;
end;
TIFooMyWrapper = class(TInterfacedMyWrapper<IFoo>, IFoo)
property Intf: IFoo read PropGetIntf implements IFoo;
end;
Aber das zwingt mich, eine separate Klasse für jede Schnittstelle zu definieren. I'ld mag eher schreiben:
TInterfacedMyWrapper<IFoo>.Create(CompToWrap);
Herausgegeben (etwas mehr Kontext, meine Ziele zu erklären - ich hoffe, es ist nicht zu verwirrend ...):
ich mehrere Klassen abgeleitet von TFooComp
, die nicht geändert werden kann. Und ich habe eine Wrapper-Klasse TMyWrapper
, die von TBarBase
erbt. Ich kann TBarBase
nicht ändern. TMyWrapper
ist ein Wrapper für TFooComp
(Art von Adaptermuster).
Jede TFooComp
-abgeleitete Klasse kann eine Schnittstelle freilegen. Was ich erreichen möchte, ist, dass TInterfacedMyWrapper
diese Schnittstelle ebenfalls offen legt (und an die wrapped TFooComp
delegiert).
Dies funktioniert irgendwie:
constructor TMyWrapper.CreateNew(AOwner: TComponent; FooClass: TFooClass);
begin
FWrappedFooComp := FooClass.Create(Self);
//...
end;
//...
function TInterfacedMyWrapper<T>.PropGetIntf(): T;
begin
//see http://stackoverflow.com/questions/4418278/use-of-supports-function-with-generic-interface-type
if not Supports(FWrappedFooComp, GetTypeData(TypeInfo(T))^.Guid, Result) then
raise Exception.Create('Interface not implemented');
end;
Aber für jede TFooComp
abgeleitete Klasse Ich habe eine eigene Wrapper-Klasse erstellen (mit nur einer Erklärung):
TWrappedFooXxx = class(TInterfacedMyWrapper<IXxx>, Ixxx)
property Intf: IXxx read PropGetIntf implements IXxx;
end;
, dass ich die Verwendung folgender Weg:
Result := TWrappedFooXxx.CreateNew(Owner, TFooXxx);
Result.DoSomething();
(Result as IXxx).DoSomeMore();
Die Notwendigkeit, einen eigenen Wrapper zu erstellen c Lass ist, was ich versuche zu vermeiden. Ich würde lieber nur schreiben:
Result := TInterfacedMyWrapper<IXxx>.CreateNew(Owner, TFooXxx);
Result.DoSomething();
(Result as IXxx).DoSomeMore();
Ein kleines, aber vollständiges Beispielprogramm wäre besser gewesen, denn dann müssten wir die Typen einiger Dinge nicht erraten (wie "TBarBase" von "TInterfacedObject" erbt oder nicht oder welcher Typ "Ergebnis" in den letzten beiden ist) Schnipsel) –
@StefanGlienke Der echte Code, ist Code, den ich sowieso veröffentlichen wollte. Ich wollte diese Frage nur vor der Veröffentlichung prüfen. Ich habe versucht, diese Frage so zu stellen, dass sie nicht zu eng wird. Aber Sie haben Recht. Ich werde den echten Code aufräumen, ihn veröffentlichen, einen Link zur Verfügung stellen und hier ein Beispielprogramm bereitstellen. (Zu Ihren Fragen: 'TBarBase' und' TMyWrapper' erben von 'TComponent' und implementieren so' IInterface'. Der Typ von 'Result' wird durch den Konstruktor' CreateNew' bestimmt, der von TMyWrapper abgeleitet ist. – yonojoy