A feature overlooked by many Delphi programmer was already introduced in Delphi 1 which is more or less the same as in the Delphi 2007 documentation at [WayBack] Type Compatibility and Identity.
There is a distinction between these explained in the above link:
type
TMyInteger1 = Integer;
TMyInteger2 = type Integer;
Where TMyInteger1 is an alias for Integer, TMyInteger2 introduces a new type which is distinct from Integer and TMyInteger. That way the compiler can set them apart, and even generates separate RTTI (Run-Time TypeInformation) for them.
Probably the most used distinct types are these:
TDateTime = type Double;
...
TDate = type TDateTime;
TTime = type TDateTime;
TFontName = type string
These are unlike TColor which is defined as “just” a subrange of Integer, but because it is a subtype, also gets a distinct type:
TColor = -$7FFFFFFF-1..$7FFFFFFF;
Type identity is important because Delphi 1 introduced these mechanisms:
- the streaming instances and their properties
- editing instances and properties in the object inspector
- two way binding of designer (form/datamodule/frame/…) and the underlying Pascal source
Without them, very basic Delphi features would not work.
In addition, a lot of other RTTI based code now enables features like object relational mapping, binding to JSON/XML and many others.
What I did not know is that the Pascal and Delphi type systems have been heavily influenced by ADA. Luckily Lutz Donnerhacke pointed me to ADA [WayBack] Types and Subtypes.
Example
I made an example Distinct type types in Delphi · GitHub showing the differences on RTTI level in these properties:
property IntegerProperty: Integer read FIntegerField write FIntegerField;
property ColorProperty: TColor read FColorField write FColorField;
property DoubleProperty: Double read FDoubleField write FDoubleField;
property DateTimeProperty: TDateTime read FDateTimeField write FDateTimeField;
property DateProperty: TDate read FDateField write FDateField;
property TimeProperty: TTime read FTimeField write FTimeField;
property StringProperty: string read FStringField write FStringField;
property FontNameProperty: TFontName read FFontNameField write FFontNameField;
The generated table (see also the source below using [Archive.is] TRttiContext added in Delphi 2010) indeed shows distinct types on the RTTI level:
Name |
Type.Name |
Type.QualifiedName |
Type.TypeKind |
IntegerProperty |
Integer |
System.Integer |
tkInteger |
ColorProperty |
TColor |
System.UITypes.TColor |
tkInteger |
DoubleProperty |
Double |
System.Double |
tkFloat |
DateTimeProperty |
TDateTime |
System.TDateTime |
tkFloat |
DateProperty |
TDate |
System.TDate |
tkFloat |
TimeProperty |
TTime |
System.TTime |
tkFloat |
StringProperty |
string |
System.string |
tkUString |
FontNameProperty |
TFontName |
System.UITypes.TFontName |
tkUString |
This post was inspired by an interesting discussion on [WayBack] What’s the technical term for the following construct: type intx = type integer; type inty = integer; What term would you use to describe the differen… – Johan Bontes – Google+
Documentation:
RTTI dump inspired by [WayBack] delphi – How can I distinguish TDateTime properties from Double properties with RTTI? – Stack Overflow.
–jeroen
Read the rest of this entry »