Interfaces are a bit of a funny feature in native code Delphi — a fairly basic construct, and indeed, one around since Delphi 3, yet implemented in a manner that makes their use needlessly fiddly outside of their original purpose, which was to be a support feature for COM development.* Ever cursed how interface types appear to support inheritance, but don’t really (e.g., a class needs to explicitly implement every interface down the inheritance tree rather than just the bottom one)? Or how you have to be careful about not leaving danging interface references about, since a virtual method call (namely, to _Release) *will* be made behind your back (and what do you mean, ‘but _Release isn’t a virtual method on the implementing object…’)? Or how you have to concentrate when using runtime-only TXMLDocument instances in ways irrelevant for runtime-only components generally? Blame the Delphi 3 engineers baking COM conventions into the language!
With that in mind, I thought it very much a Good Thing when Malcolm Groves reported how yet another COM-related quirk — namely, the inability to cast from an interface to an object reference — will be removed in Delphi 2010, a thought strengthened when I read Allen Bauer’s subsequent post on the not particularly gory details. The one quibble I have, though, is how the new feature is being presented, viz., as the ability to cast from an interface to the implementing object. For, if we leave aside COM-specific issues and think of what an interface is in principle, surely the answer is, nothing more and nothing less than a collection of methods. What, though, is an object? In short, a collection of methods + other stuff. At heart, an object — any object! — is thus a strict superset of an interface. In querying for a particular class from an interface reference, then, what you’re doing is querying for just another ‘interface’ type. Think of it like that, and the fact that an ‘EInvalidCast’ exception will be raised upon trying to cast from an external interface not implemented in Delphi, far from being a limitation or quirk of the new feature, makes sense — for, any Delphi class will be an ‘interface’ that ‘extends’ the TObject ‘interface’, and by definition, no externally-authored object will do that.
Anyhow, on reading Allen Bauer’s post, I wondered how far (and how easily) the technique D2010 uses can be employed in earlier versions. Ten minutes playing around gave an answer. More on that next time though…
* Knowing nothing about the internal discussions at the time, I should probably hedge and say motives may have been mixed — at least, Java emerged in the same timeframe with interface types as a first class language feature not designed to support for any particular external API. The fact that the base Delphi interface type was called IUnknown rather than IInterface up until Delphi 6 emphasises the Delphi engineers’ COM-centric mindset though.