有没有办法从父类调用子类的创建?下面是这个Duplicate方法,我希望调用子类的构造函数,以便底部的测试成功.
type
IBla<T> = interface(IInvokable)
['{34E812BF-D021-422A-A051-A492F25534C4}']
function GetIntFromIface(): Integer;
function Duplicate(): IBla<T>;
end;
TClassA<T> = class(TInterfacedObject, IBla<T>)
protected
function GetInt(): Integer; virtual;
public
function GetIntFromIface(): Integer;
function Duplicate(): IBla<T>;
end;
TClassB = class(TClassA<Integer>, IBla<Integer>)
protected
function GetInt(): Integer; override;
end;
function TClassA<T>.Duplicate: IBla<T>;
begin
Exit(TClassA<T>.Create());
end;
function TClassA<T>.GetInt: Integer;
begin
Exit(1);
end;
function TClassA<T>.GetIntFromIface: Integer;
begin
Exit(GetInt());
end;
function TClassB.GetInt: Integer;
begin
Exit(2);
end;
procedure TestRandomStuff.Test123;
var
o1, o2: IBla<Integer>;
begin
o1 := TClassB.Create();
o2 := o1.Duplicate();
Assert.AreEqual(o2.GetIntFromIface, 2);
end;
Run Code Online (Sandbox Code Playgroud)
您可以使用 RTTI 来执行此操作:
uses
System.Rtti;
....
function TClassA<T>.Duplicate: IBla<T>;
var
ctx: TRttiContext;
typ: TRttiType;
mthd: TRttiMethod;
inst: TValue;
begin
typ := ctx.GetType(ClassInfo);
mthd := typ.GetMethod('Create');
inst := mthd.Invoke((typ as TRttiInstanceType).MetaclassType, []);
inst.AsObject.GetInterface(IBla<T>, Result);
end;
Run Code Online (Sandbox Code Playgroud)
很可能有一种更简洁的方法来使用 RTTI 调用构造函数(我对 Delphi 中的 RTTI 几乎一无所知),因此您最好阅读该主题,而不是将上述内容视为执行此操作的规范方法。
当然,这假设所有子类都使用TObject
. 这可能相当有限。如果您发现自己必须以更基本的方式重新思考设计,我不会感到惊讶。
如果您的子类都没有实现构造函数,那么您可以使其变得更简单,并且根本不使用 RTTI:
function TClassA<T>.Duplicate: IBla<T>;
begin
ClassType.Create.GetInterface(IBla<T>, Result);
end;
Run Code Online (Sandbox Code Playgroud)
但请注意,这会调用 中定义的构造函数TObject
,并且不会调用子类中定义的任何构造函数。