Wednesday, March 14, 2007

DN4DP#4: Setting new records

This post continues the series of The Delphi Language Chapter teasers from Jon Shemitz’ .NET 2.0 for Delphi Programmers book. Last time we talked about the new capability of nesting types and constants inside other class declarations. This time we will look at the extended and OOP-like syntax and functionality for plain old record types.

Note that I do not get any royalties from the book and I highly recommend that you get your own copy – for instance at Amazon.

"Setting new records

Records have now been upgraded to proper object-oriented citizens[1]. Instead of being just a collection of passive fields, a record declaration can now contain most of the features of a full-fledged class. This includes visibility specifiers (private, strict private and public), instance methods, constructors (as long as they have at least one parameter), static class methods, class fields, class properties, class constructors (only in .NET) and nested types and constants.

Records do not support inheritance, virtual methods, protected sections, destructors or constructors with no parameters. In .NET a record can implement one or more interfaces and it is also possible to forward-declare a record (just like you can with classes). From the OORecords project

TFoo = record; // forward record declaration
IRecordInterface = interface
procedure Method(Foo: TFoo);
TFoo = record(IRecordInterface)
strict private
class constructor ClassCreate;
procedure Method(Foo: TFoo);
class var FCount: integer;
var FBar: integer;
procedure SetBar(const Value: integer);
class procedure SetCount(const Value: integer); static;
constructor Create(ABar: integer);
property Bar: integer read FBar write SetBar;
class procedure ReportCount; static;
class property Count: integer read FCount write SetCount;

It is useful to be able to declare methods as part of a lightweight record object[2] instead of encoding them in separate global routines (as has been customary in native Delphi). This couples data and behavior in a way that is object-oriented, easy to understand and easy to share with other languages. Records with methods is also a requisite for supporting operator overloading, which brings us to our next topic [operator overloading - which we will look at in the next DN4DP blog post - Ed.]

[1] Old time Delphi and Turbo/Borland Pascal programmers may remember the old object style classes that could also be used as a kind of object oriented records. Borland chose to extend the record concept instead of reviving the deprecated object syntax, mostly to avoid breaking old code. The old object model supported inheritance and a number of other features that the new OOP records don’t (and cannot in .NET).

[2] See Chapter 5 for more details of value types vs. reference types."

1 comment:

Anonymous said...

"The old object model supported inheritance and a number of other features that the new OOP records don’t (and cannot in .NET)"

Frankly, I find frightening that Object Pascal syntax and features are dictated by another company and another language. One of the strong point Delphi had against C++ was its freedom in implementation. While C++ had often to follow awkward standards, Delphi didn't and could come up with better implementation. Now this freedom is gone.

Copyright © 2004-2007 by Hallvard Vassbotn