Vorsicht! Bitte denken Sie daran, dass alle Aussagen, die auf der Borland-Konferenz zu Delphi for .NET und Delphi 7 gemacht wurden, immer von Safe Harbor Statements (can be subject to change without notice) begleitet wurden. Die Erfahrung zeigt, dass sich in einem halben Jahr noch viel ändern kann ...
Bereits in der Opening Keynote der Borcon wurde ein kleines Delphi-Programm gezeigt, das sowohl auf einem normalen Windows-Rechner als auch auf einem Handheld-PC lief. Allerdings fiel hier kein einziges Mal das Stichwort Delphi for .NET. Der eine oder andere Teilnehmer kam dann auch etwas verwirrt aus der Eröffnungssession und träumte von Delphi-Programmen für Handhelds mit Nicht-Microsoft-Betriebssystemen. Das wird wohl für die nahe Zukunft weiterhin ein Traum bleiben, sofern für das jeweilige Betriebssystem keine .NET-Umgebung zur Verfügung steht. Nativer Maschinencode für unterschiedliche Prozessoren ist die vorgebene Marschrichtung für den Borland C++ Compiler, der in seiner Architektur komplett überarbeitet wurde und durch eine dreischichtige Architektur leichter an andere Prozessoren wie Strong Arm angepasst werden kann. Um native Programme für Nokia-Handys zu schreiben, kommt man um C++ wohl leider nicht herum.
In der Keynote am ersten Tag, gehalten von Anders Hejlsberg, dem inzwischen zu Microsoft gewechselten Vater von Turbo Pascal und Delphi, war es dann so weit. Nach einer Einführung in .NET zeigte Hejlsberg ein bisschen Live Coding mit ASP.NET und Notepad als Entwicklungswerkzeug, das darin gipfelte, dass er Delphi als Script Processor im HTML-Code eintrug und eine Ereignisbehandlungsroutine im klassischen Pascal für die ASP-Seite programmierte. Besser hätte man die Integrationsmöglichkeiten, die .NET bietet, nicht zeigen können. Sicherlich ist es für einen Delphi-Entwickler gewöhnungsbedürftig zu sehen, wie Delphi als Scripting Engine bezeichnet und eingebunden wird. Überraschenderweise gab Hejlsberg als Microsoft-Mitarbeiter dann auch den .NET-Fahrplan und die Codenamen der nächsten Delphi-Versionen bekannt: In der zweiten Jahreshälfte erscheint zunächst Delphi 7 ( Codename Aurora ), das bereits Spracherweiterungen für .NET enthält, aber noch ein nativer Compiler ist. Mit im Paket ist ein Preview von Delphi for .NET, der wahrscheinlich aus dem Großteil des Frameworks und dem Kommandozeilencompiler besteht. Erst Anfang 2003 wird das richtige Delphi for .NET (Codename Galileo) als eigenes Produkt erscheinen. Delphi for .NET erzeugt dann keinen Maschinencode mehr sondern nur noch die Intermediate Language MSIL und ist damit eigentlich gar kein richtiger Native Code Compiler mehr. Der angekündigte Zeitplan war für die meisten anwesenden Delphi-Entwickler enttäuschend. Ein richtiges Delphi for .NET erst in einem Jahr ist ausgesprochen spät.
Sanfte Migration
Borland hat diesen Weg bewusst gewählt, um Delphi-Entwicklern eine sanfte Migration zu ermöglichen. Anders als das Microsoft Visual Basic-Entwicklern zugemutet hat bzw. zumuten musste, die zu Visual Basic .NET wechseln, sollen Delphi-Anwender mit möglichst überschaubarem Aufwand ihre Anwendungen portieren können. Diese größtmögliche Kompatibilität und Portabilität sei es, die diese Zeit benötigt, war die übereinstimmende Aussage aller Borland-Mitarbeiter. Danny Thorpe, Architekt des Delphi-Compilers sieht in Delphi 7 den nächsten großen Evolutionsschritt des Compilers, den er in eine Reihe stellt mit den grundlegenden Änderungen in Turbo Pascal 3 und 5.5 (Units und Objektorientierung) sowie Delphi 1 (Objektmodell mit RTTI). Die Common Language Specification von .NET erzwingt einige neue Sprachfeatures wie Namespaces, statics und Attributen in Klassen, die zum Teil auch Eingang finden sollen in den nativen Compilern unter Linux und Windows.Änderungen für .NET
Zunächst erzeugen Sprachen, die .NET unterstützen, keinen nativen Code mehr, sondern CIL (Common Intermediate Language). Ein konkret erzeugtes Paket in CIL wird in .NET Syntax Assembly genannt. Vom Informationsgehalt sind die Assemblies vergleichbar mit Packages in Delphi, wenn man die Informationen der dcp-Datei mit denen der bpl-Datei kombiniert. Der CIL-Code enthält neben den Instruktionen noch Typinformationen und bleibt damit für den Just-In-Time Compiler (JIT) überprüfbar. Der JIT prüft bei der Kompilierung den CIL-Code auf Typsicherheit, Speicherbedarf und auch Rechte (so genannter Managed Code). Analog der Java Virtual Machine implementiert .NET Garbage Collection für verwendeten Speicher.Jede Sprache, die .NET vollständig unterstützt, muss sich an den Sprachspezifikationen von Microsoft orientieren (Common Language Specification, CLS) und sich gegebenfalls den festgelegten Regeln der CLS unterwerfen. Ein Teil der CLS ist auch eine gemeinsame Grundlage von Datentypen, das so genannte Common Type System (CTS). Dank dieser gemeinsamen Grundlage sind Komponenten unterschiedlicher Sprachen miteinander verwendbar und können sich Klassenhierarchien über verschiedene Sprachen erstrecken. Alle .NET-Sprachen verwenden zudem ein gemeinsames Objektmodell und Basisobjekt, die Bestandteil der gemeinsamen Bibliothek sind (Common Language Runtime, CLR). Die Ausnahme von dieser Regel liefert Microsoft mit J#, welches auf dem Basisobjekt der CLR System.Object eine eigene Klassenhierarchie definiert. Jede Programmiersprache, die zu hundert Prozent kompatibel sein will, muss sich also etwas verbiegen, um sich an die vorhandenen Spezifikationen anzupassen. In gewisser Weise führt dies auch zu einer Nivellierung zwischen den Sprachen - seit Visual Basic.NET ist eben auch VB wirklich objektorientiert und versteht Vererbung.
Delphi Anpassungen
Damit Delphi sich nahtlos in das .NET-Framework einfügen kann, sind Änderungen an den Datentypen, Klassen und Bezeichnern unumgänglich. Ab Delphi 7 soll der Compiler beispielsweise Namespaces unterstützen. Bestehende Namespaces aus .NET werden wie Units eingebunden, sodass eine Uses-Anweisung in Delphi for .NET zum Beispiel so aussehen könnte:Uses System.IO.Text, System.Web , System.Windows.Forms;
Compiler Magic bei Klassen
Das Kennzeichen des Klassenmodells von Delphi, die Zwangsvererbung von Tobject, findet sich in dieser Form auch bei .NET. Alle Objekte stammen von System.Object ab. Die Klasse TObject von Delphi wird, wie einige andere Klassen auch, direkt auf diesen Typ aus der CLR gemappt, wie dies zur Zeit mit TWinControl und TWidgetControl oder IUnknown und IInterface der Fall ist. In der Unit System wird man bei Delphi für .NET den Quelltext von TObject nur noch als Einzeiler sehen :typeTObject = System.Object;
System.Object hat lediglich die vier publizierten Methoden Equals, GetHashCode, ToString und GetType. Damit nach wie vor Code kompiliert, der auf Funktionen wie ClassName und ClassInfo zugreift, ist der Einsatz von Hilfsklassen geplant, die Aufrufe dieser Methoden automatisch umsetzen. Diese Hilfsklassen stellen lediglich eine Hilfe für den Compiler dar und ermitteln die benötigten Informationen über die von System.Object mit der Methode GetType bereitgestellten Typinformationen. Auch wenn das Konzept etwas unsauber wirkt, stellt es einen guten Kompromiss dar, der es möglich macht, ohne fundamentale Änderungen an bestehendem Sourcecode auszukommen. Der Borland-typische, ergebnisorientierte Pragmatismus eben. Langfristig sollten sich Delphi-Entwickler dann doch lieber mit der Reflection-Klasse aus dem .NET-System auseinandersetzen, zumal es unwahrscheinlich ist, dass die alten Methoden noch in der Programmierhilfe angezeigt werden. Für diverse weitere Basisklassen des Delphi-Laufzeitsystems gilt Ähnliches. Tabelle 1 gibt einen Überblick über das geplante Type-Mapping.
|
Neue Features in Klassen
Dank .NET finden auch einige Erweiterungen Eingang in das Objektmodell von Delphi, die bei einigen Entwicklern schon länger auf der Wunschliste stehen. Ab Delphi 7 wird es wahrscheinlich möglich sein, in Klassen sowohl Eigenschaften als auch Konstanten und statische Klassenmethoden zu definieren. Ebenso werden verschachtelte Klassendeklarationen (Nested Types) erlaubt sein:typeTDelphi7Sample = classclass StaticData : Integer;class property demo : String ...;class static procedure Test;type TNested = classprocedure Ping;end;end;
Zusätzlich zu den vordefinierten Attributen können eigene Attribute definiert werden, die sich von der Basisklasse TCustomAttribute ableiten. Analog C# geben Sie Attribute auch in Delphi 7 in eckigen Klammern vor dem Bezeichner an:
typeTMyAttribute = Class(TCustomAttribute)constructor Create(Name: String);...end;[TMyAttribute ('Strange looking')]TMyClass = class[Datenattribut]FData : Integer;[WebMethod, DebuggerStepThrough]function ProvideService: String;end;
Verlierer bei .NET
Von einigen Sprachelementen muss man sich allerdings bei Delphi for .NET (nicht unbedingt bei Delphi 7) verabschieden. Der aus aus Kompatibilitätsgründen zu Turbo Pascal bisher noch mitgeschleppte 6-Byte Gleitkommawert Real48 gehört ebenso dazu, wie das alte Schlüsselwort object für Borland Pascal-kompatible Objekte. Pointer, Speicherallokationen und unsichere Typecasts vertragen sich nicht mit safe und managed Code unter .NET. Entsprechend verschwinden der Operator @ , untypisierte Parameter, die Direktive absolute sowie die Prozeduren und Funktionen Addr, GetMem, FreeMem und ReallocMem. Als Workaround für den notorischen Byte-Fummler empfahl Danny Thorpe dynamische Arrays zu verwenden. Als Trostpflaster für diejenigen, die immer noch die alten Borland Pascal-Objekte einsetzen, können Erweiterungen für den Record in Pascal herhalten. In einer Record-Definition können demnächst auch statische Methoden enthalten sein:TCustomer = recordCustNo : Integer;Name : Integer;procedure Rename( NewName: String);end;
VCL oder Windows.Forms?
Delphi für .NET wird sowohl GUI-Design mit Microsoft-Klassen aus System.Windows.Forms als auch GUI-Design mit einer VCL-Variante anbieten. Welche Variante gewählt wird, hängt vom Einsatzzweck und den Vorlieben des Entwicklers ab. Für die Portierung einer bestehenden Anwendung wäre es sicherlich unsinnig, alles umzuschreiben. Bei einem neuen Projekt allerdings ist die Auswahl schon eine Überlegung wert. Das VCL-Framework für .NET setzt genauso wie System.Windows.Forms direkt auf der Windows-API auf und hat eine eigene Schnittstelle zum unmanaged Code der API. Es ist also kein zusätzlicher Wrapper für die bestehenden Klassen, sondern greift parallel auf die API zu. Änderungen in Aussehen und Funktion an den .NET-Klassen, die sich durch einen Wechsel des Systems/Service Packs oder Internet Explorers ergeben, lassen eine GUI-Anwendung, die auf VCL basiert, eher unbeeindruckt. Die Portierbarkeit auf andere Windows-Plattformen, wie beispielsweise PocketPC, ist schon bei Windows.Forms-basierenden Anwendungen nur eingeschränkt möglich und dürfte bei VCL-Anwendungen gänzlich unmöglich sein. Für die Weitergabe haben Anwendungen, die auf dem VCL-Framework basieren, zudem mehr Overhead, da in der Regel nur die Klassen für Windows.Forms installiert sind. Die Trennung zwischen Eigenschaftsdaten und Code in separaten Dateien wird für das VCL-Framework in jedem Fall beibehalten. Entwickler, die sich schon immer an der DFM-Datei gestört haben, werden eher zu Windows.Forms tendieren.Das Package-Konzept wird im übrigen in ähnlicher Form beibehalten. Ein Assembly in .NET enthält zusätzlich zum Code in Intermediate Language die Symbolinformationen und entspricht damit in etwa einem Delphi-Package inklusive DCP-Datei. Fremde Komponenten in .NET-Assemblies bindet Delphi for .NET wie Packages ein. Für eigene Anwendungen und Delphi-Packages (bzw. Delphi-Assemblies) hat der Entwickler nach wie vor die Möglichkeit, mit oder ohne Laufzeit-Assemblies zu arbeiten. Entweder wird die Anwendung kleiner und benötigt auf dem Zielsystem die verwendeten Assemblies oder der Code aus einem Borland-Assembly wird direkt gelinkt, ohne dass auf dem Zielsystem die verwendeten Assemblies vorhanden sein müssen.


