From LordCrc, 8 Years ago, written in Delphi (Object Pascal).
Embed
  1. type
  2.   IWidget = interface(IInvokable)
  3.     function GetId: string;
  4.     function WidgetType: string;
  5.  
  6.     property Id: string read GetId;
  7.   end;
  8.  
  9.   TWidget = class(TInterfacedObject, IWidget)
  10.   private
  11.     FId: string;
  12.     function GetId: string;
  13.   public
  14.     constructor Create(const Id: string);
  15.     function WidgetType: string; virtual; abstract;
  16.  
  17.     property Id: string read GetId;
  18.   end;
  19.  
  20.   TRoundWidget = class(TWidget)
  21.   private
  22.     FRadius: double;
  23.   public
  24.     constructor Create(const Id: string; const Radius: double);
  25.     function WidgetType: string; override;
  26.  
  27.     property Radius: double read FRadius;
  28.   end;
  29.  
  30. { TWidget }
  31.  
  32. constructor TWidget.Create(const Id: string);
  33. begin
  34.   inherited Create;
  35.  
  36.   FId := Id;
  37. end;
  38.  
  39. function TWidget.GetId: string;
  40. begin
  41.   result := FId;
  42. end;
  43.  
  44. { TRoundWidget }
  45.  
  46. constructor TRoundWidget.Create(const Id: string; const Radius: double);
  47. begin
  48.   inherited Create(Id);
  49.  
  50.   FRadius := Radius;
  51. end;
  52.  
  53. function TRoundWidget.WidgetType: string;
  54. begin
  55.   result := 'Round';
  56. end;
  57.  
  58.  
  59. var
  60.   widget: TWidget;
  61.   iw: IWidget;
  62.   f: RIFunc<string>; // type RIFunc<R> = reference to function(const Instance): R;
  63.   r: RIFunc<double>;
  64.   id, wt: string;
  65.   rad: double;
  66. begin
  67.   widget := TRoundWidget.Create('42', 42);
  68.  
  69.   try
  70.     f := RIConstructor<TWidget>.PropGetter<string>('Id');
  71.     id := f(widget);
  72.     WriteLn(id);  // 42
  73.  
  74.     r := RIConstructor<TRoundWidget>.PropGetter<double>('Radius');
  75.     rad := r(widget);
  76.     WriteLn(rad); // 4.20000000000000E+0001
  77.  
  78.     f := RIConstructor.Func<string>(TypeInfo(TWidget), 'WidgetType');
  79.     wt := f(widget);
  80.     WriteLn(wt);  // Round
  81.  
  82.  
  83.     iw := TRoundWidget.Create('abc', 123);
  84.  
  85.     f := RIConstructor.PropGetter<string>(TypeInfo(IWidget), 'Id');
  86.     id := f(iw);  
  87.     WriteLn(id);  // abc
  88.    
  89.   finally
  90.     widget.Free;
  91.   end;
  92. end.