Did you know….
03 Oct
.. that you can do nested classes in Delphi, both in Win32 and .Net?
program Project27; {$APPTYPE CONSOLE} uses SysUtils; type TOuterClass = class private type TNestedClass = class public procedure DoThis; end; private FNestedClass: TNestedClass; public constructor Create; destructor Destroy; override; property NestedClass: TNestedClass read FNestedClass; end; { TOuterClass } constructor TOuterClass.Create; begin FNestedClass := TNestedClass.Create; end; destructor TOuterClass.Destroy; begin FNestedClass.Free; inherited; end; { TOuterClass.TNestedClass } procedure TOuterClass.TNestedClass.DoThis; begin Writeln(‘Doing this‘); end; var OuterClass: TOuterClass; begin try OuterClass := TOuterClass.Create; try OuterClass.NestedClass.DoThis; finally OuterClass.Free; end; Readln; except on E:Exception do Writeln(E.Classname, ‘: ‘, E.Message); end; end.


Nested classes are very useful for implementing "local" classes such as Enumerators: Instead of defining TMyClassEnumerator as a public class, you define TMyClass.TEnumerator as a private nested class.
Besides keeping the namespace a little tidier, it allows you to restrict access to classes that you are forced to declare publicly (such as enumerators).
October 3rd, 2007 at 9:15 pmHi Nick,
this highlights one of the disadvantages of having to fully declare classes in the interface section of a unit: Since the nested class is private, there is no need for it to be part of a unit’s interface section, it only confuses programmers who use the class.
This would be much tidier if it were possible to declare anything that’s private in the implementation section only. IIRC there is at least one QC report on this issue.
twm
October 4th, 2007 at 2:17 amC Johnson –
Probably the best example is a collection with a specific collection type. The specific type is meaningless outside the context of the collection itself, so it makes sense to nest it within the collection itself.
Nick
October 4th, 2007 at 8:04 amUsers of Delphi 2005 should be aware of QC 11331. The compiler will accept some nested-class code that it shouldn’t accept. The bug was fixed for Delphi 2006, apparently.
Marshall cites an enumerator as a good candidate for a nested class, but it shouldn’t be a _private_ nested class. It should be public. That lets consumers of the class enumerate its contents. Maybe the "for-in" loop can use a private nested class, but the rest of us can’t, and not all enumerations fit the "for-in" model.
And Nick, your code isn’t valid. It’s using left single quotation marks instead of apostrophes. Delphi doesn’t support curly quotes, does it?
October 4th, 2007 at 8:26 amRob –
I copied the code right out of the Code Editor and pasted it into a formatting tool. That may have done something to the font.
Nick
October 4th, 2007 at 8:44 amWhat tool do you use for code formatting, Nick? FWIW, YAPP (http://lingua.codegear.com/yapp/) doesn’t seem to suffer from the same problem with the quotes.
October 4th, 2007 at 11:41 amThe code example looks strange for me - TNestedClass type declared as private while property NestedClass: TNestedClass is made public. What difference it makes if I declare TNestedClass type in public section of TOuterClass?
October 4th, 2007 at 10:24 pmSerg –
This is just typical information hiding — the actual declaration of the class doesn’t matter and thus isn’t made public. The property exposes the functionality.
You can, of course, design things totally differently if you like.
Nick
October 5th, 2007 at 8:26 amCleggy –
I’m using a LiveWriter plugin — unfortunately, I can’t seem to find the name of it.
I can tweak the formatting, so I’ll give that a look.
Nick
October 5th, 2007 at 8:27 am