When I first heard of ‘strict private’ and ‘strict protected’ being introduced into the Delphi language, I thought, ‘what’s the point, beyond .Net compatibility?’ In the case of strict private though, I’m now a complete convert, the main reason being its forcing any library code you write to be more descendant-friendly when the descendants lie outside of the original unit, ‘native’ descendants (if you will) not being able to get at crucial internals of the base class that foreign descendants are barred from. In saying this, I don’t mean to make a categorical claim that non-strict private sections are inherently evil, just that using strict private as a matter of course prevents you from unwittingly creating obstacles to descendants defined in other units.
So, what of strict protected? Is that a good thing too? Here I would still say ‘no’ — I just don’t ‘get’ the philosophical reasons against the ‘friend’ semantics of Delphi’s traditional protected visibility. More to the point, if Anders Hejlsberg had been of that mind back in 1993-4, a classic Delphi hack would never have been possible. I speak, of course, of the following trick –
type TControlAccess = class(TControl); procedure SetControlText(Control: TControl; const Text: string); begin TControlAccess(Control).Text := Text; end;
Now, one might just say a hack is a hack and so a bad thing in principle. On the other hand, with the VCL as it is currently designed, it’s pretty essential if controls are to be used polymorphically. Sure, I realise there’s the RTTI alternative, but this takes more lines of code and in being more complicated is more error prone in my opinion.
Nonetheless, there is a superior, though currently hypothetical alternative, one that the Delphi engineers actually implemented in an selective fashion for VCL.NET – namely, for each base class to implement an interface containing the various properties it introduces at the protected level of visibility. Assuming a IControlAccess interface were to be created for TControl, the ‘hacky’ code I just gave could be re-written cleanly as thus:
procedure SetControlText(Control: TControl; const Text: string); begin (Control as IControlAccess).Text := Text; end;
Now, even if the VCL proper were to have such interfaces added to it, this still wouldn’t legitimate retrospectively lowering the visibilty of all protected sections to strict protected — there’s simply too much existing code that assumes the possibility of the ‘hack’ just mentioned. Nonetheless, it would at least allow people to be ‘good’ from now on without the difficulties of using RTTI.