Explicit interface implementations solved for Delphi 8
published: Sat, 17-Jan-2004 | updated: Thu, 27-Oct-2005
A few days ago I was trying to solve a particular problem with Delphi 8 that was somewhat easy in C#: implementing interfaces explicitly. (You can read about it here.)
It turns out that I was almost there, but wasn't seeing or making the final step. A reader from Russia (Arioch), whom I understand is not even a Delphi programmer (do I have egg on my face, or what? <g>), made a couple of suggestions to try and solve the problem, one of which worked beautifully.
Here's the suggestion tnat worked, which I've converted into a small test app.
program Test; {$apptype console} uses System.Collections; type Foo = class(TObject, ICloneable) private protected function i_Clone : TObject; public // implement ICloneable function ICloneable.Clone = i_Clone; // the Clone we really want function Clone : Foo; end; function Foo.i_Clone : TObject; begin Console.WriteLine('Enter i_Clone'); Result := Clone; Console.WriteLine('Leave i_Clone'); end; function Foo.Clone : Foo; begin Console.WriteLine('Enter Clone'); Result := Foo.Create; Console.WriteLine('Leave Clone'); end; var f : Foo; f2 : Foo; f3 : Foo; begin Console.WriteLine('Create a Foo'); f := Foo.Create; Console.WriteLine('Clone the Foo directly'); f2 := f.Clone; Console.WriteLine('Cast the Foo to an ICloneable instance, then clone it'); f3 := Foo(ICloneable(f).Clone); end.
The thing to notice here is that the ICloneable.Clone method is pointing directly to a protected method with the right signature, but with a different name. My previous attempts tried to point the ICloneable.Clone method to another method called Clone, which messed me up with method overload errors. (By the way, I know that Clone isn't really cloning anything, the code is there just to make sure the test app compiles.)
The result of running the app is what we'd expect:
C:\TestApps>test Create a Foo Clone the Foo directly Enter Clone Leave Clone Cast the Foo to an ICloneable instance, then clone it Enter i_Clone Enter Clone Leave Clone Leave i_Clone
As you can see, this solution gives me the effect I wanted: a class that implements an interface, and a way of 'hiding' the interface's non-type-safe methods in favor of type-safe versions. Thanks, Arioch!