Einige wichtige Dinge, die man beachten sollte
Wie bei allen Veränderungen, gibt es auch hier ein paar Fettnäpfchen, auf welche man achten sollte. Drei Punkte die man beachten und überprüfen sollte, wenn man auf seltsame Fehler stößt.
Benutze immer Packages
Borland hat immer empfohlen
nicht die
Library Projekte zu nutzen, um Assemblies zu erstellen. In Delphi 2005 ist der Compiler dahingehend strikter und erlaubt es einem nicht mehr Anwendungen zu erstellen, welche auf eine Delphi-Library verweisen.
Man sollte daher
immer Packages nutzen, um .NET Assemblies zu erstellen.
Typen immer über den vollständigen Bezeichner ansprechen
Die meisten .NET Sprachen verlangen von einem den Namespace zu benutzen, um Typen eindeutig zu identifizieren oder wenn man Namespaces importiert (z.B.
using). Delphi wird jedoch
immer den Unitnamen nutzen und niemals den Namespace, um einen Typen zu nutzen. Diese Regel hält auch stand, wenn man ein Delphi-
Package eines anderen Herstellers nutzt. Delphi erkennt diese und nutzt die entsprechenden Unitnamen.
Hinweis: nutzt man Assemblies, welche in anderen Sprachen erstellt wurden, so nutzt man einfach den Namespace, um die Typen zu nutzen.
Dieser Unterschied ist häufig verwirrend. Ein einfaches Beispiel ist der Gebrauch von
TypeConverters und
Designers. Zum Bespiel: ein Typenkonvertierer in einer Delphi
Unit:
Delphi-Quellcode:
unit Sample.Controls.Design;
Type
TConverter =
class(TypeConverter)
end;
Um diesen zu nutzen nutzt man den vollständigen Namen:
Delphi-Quellcode:
Uses
Sample.Controls.Design;
type
[TypeConverter(typeof(TConverter))]
TItem = class
end;
oder
Delphi-Quellcode:
Type
[TypeConverter(typeof(Sample.Controls.Design.TConverter))]
TItem = class
end;
In C# hingegen nutzt man einfach nur den Namespace:
Code:
[b]using[/b] Sample.Controls;
[TypeConverter([b]typeof[/b](TConverter))]
[b]class[/b] TListItem {
}
bzw.
Code:
[TypeConverter([b]typeof[/b](Sample.Controls.TConverter))]
[b]class[/b] TListItem {
}
Wie dem auch sei, zu jeder Regel gibt es mindestens eine Ausnahme. Auch in Delphi gibt es verschiedene Situationen in welchen man die Namespaces nutzt.
Ein Beispiel ist die Erstellung von ASPX, ASCX und ASMX Dateien. Erstellt man zum Beispiel eine Webseite mit dem Namen
TWebForm in der Datei
Application.*Pages.*WebForm1.**pas, dann sieht das PAGE-Tag wie folgend aus:
Code:
[color=#b600ff]<%@Page Language="c#" Codebehind="WebForm1.pas" Inherits="Application.Pages.TWebForm1"%>[/color]
Ein anderer Fall ist es, wenn man Informationen zu .NET durch Strings weiterleiten will, speziell zum Beispiel, wenn man Reflektionen nutzt:
Delphi-Quellcode:
var c: TypeConverter;
[...}
c := Assembly.CreateInstance('Sample.Controls.TConverter');
Dieser feine Unterschied führt häufig zu Fehlern und Problemen und muss genauestens berücksichtigt werden, wenn man Code aus Delphi 8 importiert oder aus anderen Sprachen konvertiert.
Doppelte Typen
Nutzt man den gleichen Typenamen in zwei verschiedenen Units, welche in einem Namespace kompiliert werden, so werden zwei Klassen mit der gleichen Bezeichnung generiert. Zum Beispiel: fügt man folgende
Unit zu dem oben erstellten
Package hinzu:
Delphi-Quellcode:
unit Sample.Controls.Treeview;
interface
type
TTreeview =
class(TControl)
end;
type
TItem =
class
end;
implementation
end.
Nun hat man zwei Klassen im
Package, welche den Namen
TItem tragen. Eine wurde in
Sample.Controls.*List*view.*pas deklariert, die zweite in
Sample.Controls.*Treeview.pas. Nutzt man jetzt wieder ein Reflektor-Tool, so wird man feststellen, dass sich im Namespace
Sample.Controls zwei Klassen mit dem Namen
TItem befinden. Das kann nicht nur bei Klassentypen, sondern bei allen von Delphi unterstützen Typen (z.B. Records und Enumerationen) geschehen.
Um dieses Problem zu umgehen benennt der Compiler
alle Typen um, welche nicht ausserhalb des Assemblies sichtbar sind, anders gesagt, alles was nach dem Keyword
implementation definiert wird. Delphi erreicht das, indem der Unitnamen an alle Typenbezeichner angehangen wird.
Wie dem auch sei, gibt es zwei öffentliche Typen mit dem gleichen Namen im gleichen Namespace, so ändert Delphi nichts. Entwickler, welche andere Tools (z.B. C#) nutzen, können hier auf Probleme stoßen. Eine zukünftige Version des Delphi Compilers sollte solche Probleme erkennen und entsprechend handeln. Bis dahin empfehle ich eine Tool wie z.B.
peverify aus dem .NET
SDK zu nutzen, um solche Eventualitäten aufzudecken.