Recently, I stumbled upon a new undocumented procedural type compatibility in Delphi.
Since Delphi 10.3, "reference to procedure" is compatible with both "procedure of object" and "procedure", which means "reference to function: X" is compatible with "function: X of object" and "function: X".
Here's a short example.
If you compile the following, there's no errors.
uses System.SysUtils; procedure MyProc; begin end; function MyFunc: string; begin Exit(''); end; var AProc: TProc; AObj: TObject; AFunc: TFunc<string>; begin AObj := TObject.Create; AProc := MyProc; AProc := AObj.CleanupInstance; AProc := AObj.FreeInstance; AFunc := MyFunc; AFunc := AObj.ClassName; AFunc := AObj.ToString; end.
However, note that the compatibility is one-way though. While you can assign "procedure", or "procedure of object" to a "reference to procedure"-typed variable, you can't do it the other way though.
You'll not find any compatibility notes either here in the Procedural Types(Delphi) section, or here in the "Type Compatibility and Identity (Delphi)" section of Delphi's docwiki.
What do you think of this latest undocumented feature?
In 2017, with the release of Delphi 10.2 Tokyo, Embarcadero introduced a specialized implementation of the Observer pattern into the System.Classes unit. While it has been in the wild for 9 years, it remains a "hidden" architecture for many, primarily because it serves as the invisible engine behind LiveBindings. Other than live bindings, you can also use the Observer pattern as a way to update component settings to the Windows registry, an .ini file, or persist it elsewhere.
System.Classes