type
IWidget = interface(IInvokable)
function GetId: string;
function WidgetType: string;
property Id: string read GetId;
end;
TWidget = class(TInterfacedObject, IWidget)
private
FId: string;
function GetId: string;
public
constructor Create(const Id: string);
function WidgetType: string; virtual; abstract;
property Id: string read GetId;
end;
TRoundWidget = class(TWidget)
private
FRadius: double;
public
constructor Create(const Id: string; const Radius: double);
function WidgetType: string; override;
property Radius: double read FRadius;
end;
{ TWidget }
constructor TWidget.Create(const Id: string);
begin
inherited Create;
FId := Id;
end;
function TWidget.GetId: string;
begin
result := FId;
end;
{ TRoundWidget }
constructor TRoundWidget.Create(const Id: string; const Radius: double);
begin
inherited Create(Id);
FRadius := Radius;
end;
function TRoundWidget.WidgetType: string;
begin
result := 'Round';
end;
var
widget: TWidget;
iw: IWidget;
f: RIFunc<string>; // type RIFunc<R> = reference to function(const Instance): R;
r: RIFunc<double>;
id, wt: string;
rad: double;
begin
widget := TRoundWidget.Create('42', 42);
try
f := RIConstructor<TWidget>.PropGetter<string>('Id');
id := f(widget);
WriteLn(id); // 42
r := RIConstructor<TRoundWidget>.PropGetter<double>('Radius');
rad := r(widget);
WriteLn(rad); // 4.20000000000000E+0001
f := RIConstructor.Func<string>(TypeInfo(TWidget), 'WidgetType');
wt := f(widget);
WriteLn(wt); // Round
iw := TRoundWidget.Create('abc', 123);
f := RIConstructor.PropGetter<string>(TypeInfo(IWidget), 'Id');
id := f(iw);
WriteLn(id); // abc
finally
widget.Free;
end;
end.