Einzelnen Beitrag anzeigen

Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: Unterhaching
11.412 Beiträge
 
Delphi 12 Athens
 
#5

Re: Namespaces in Delphi 2005

  Alt 6. Dez 2004, 11:33
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.
Daniel Lizbeth