Der Delphi-Compiler ordnet bei der Übesetzung jedem Ausdruck einen Typen zu, um überprüfen zu können, ob Zuweisungen zulässig sind, ob übergebene Parameter einem kompatiblen Typen entsprechen, der ggf Konvertiert werden kann, etc.
So hat zB der konstante Ausdruck
189+4
den impliziten Typ
Byte zugeordnet. Bei einem Ausdruck der Form
4+3
jedoch den Typ
0..127 (nachzulesen in der
OH "Echte Konstanten").
Bei der Deklaration von Variablen wird idR explizit ein Typ angegeben, zB
und der Compiler ist dank dieser Information später in der Lage zu entscheiden, ob eine Zuweisung der Form
myInt:= 189+4;
zulässig ist (nachzulesen in der
OH unter "Typkomatiblität"). Darüber hinaus kann er nur durch die Angabe des Typs den Operator (nein, es ist keine Funktion)
SizeOf verwenden, also die Größe in Bytes zu einem Datentypen ermitteln, obwohl dieser Information nicht zu jeder Variablen abgelegt wird. Stattdessen greift er zu diesem Zweck auf seine eigene "Buchführung" zurück...
Es ist möglich, ohne einen benannten Typen, eine Variable zu deklarieren:
Delphi-Quellcode:
var
myVar: record
AField: Integer;
end;
Damit der Compiler später zB in der Lage ist, zu erkennen, dass die Zuweisung
myVar:= '6*9=42';
ungültig ist, aber auch um Konstrukte der Art
FillChar(myVar, SizeOf(myVar), 0);
zu ermöglichen, muss der Compiler der Variablen
myVar einen Typen zuordnen.
Aus Mangel an Unterstützung seitens des Programmiers ist der Compiler an dieser Stelle gezwungen, selbst einen Typen zu erstellen und zu ihm die notwendigen Informationen ablegen, allerdings verwendet er hierzu keinen für den Programmierer zugänglichen Namen und dieser Typ dient nur dem Compiler zur Übersetzungszeit. Wollte der Programmierer mit dieser Information arbeiten hätte er schließelich einen Typen in der Form
Delphi-Quellcode:
type
TMyType = record
AField: Integer;
end;
var
myVar: TMyType;
benannt
Wenn Du hingegen zweimal einen anonymen Typen erstellst, zB mit
Delphi-Quellcode:
var
aString: string[10];
anotherString: string[10];
wird der Compiler zweimal einen eigenen Typen erstellen, der nicht identisch ist mit dem Anderen (siehe hierzu die
OH "Typenidentität"). Welche Konsequenzen das für Dein Programm, zB bei Zuweisungen der Art
aString:= anotherString
hat, kannst Du in der
OH unter "Zuweisungskompatibilität" nachlesen.
BTW: Dies ist auch der Grund warum Signaturen von Methoden, Funktionen und Prozeduren in der Form
procedure MyProc(var AValue: record AField: Integer; end;);
unzulässig sind: Es gibt keinen kompatiblen Datentypen...
Das Prinzip, der
anonymen Datentypen ist in anderen Sprachen noch weiter vertreten, bei denen man zB ein Exemplar einer Klasse (Objekt), die von einer anderen Erbt und zu der man ad-hoc eine Methode überschreibt, erzeugen kann ohne die Klasse zu benennen
Zum Verständnis in Pseudo-PascalCode:
Delphi-Quellcode:
var
myObject: TMyClass;
anotherObject: TMyClass;
begin
myObject:= TMyClass.Create(Self);
Showmessage(IntToStr(myObject.GetValue)); // e.g. '5'
anotherObject:= (class(TMyClass)
function GetValue: Integer; overload;
begin
Result:= (inherited GetValue) + 23;
end; ).Create(Self);
Showmessage(IntToStr(anotherObject.GetValue)); // '28'
wobei folgende Aussagen wahr wären:
Delphi-Quellcode:
anotherObject.InheritsFrom(TMyClass);
anotherObject.ClassType<>myObject.ClassType;
anotherObject is TMyClass;