`
netatomy
  • 浏览: 46820 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Namespaces in Delphi 2005 by Marc Rohloff

 
阅读更多
Abstract: To make Delphi code friendlier towards other .NET languages Borland has changed the way Delphi 2005 produces namespaces. This article discusses the changes that have been made and how they affect you.

<style> <!-- /* Font Definitions */ @font-face {font-family:Wingdings; panose-1:5 0 0 0 0 0 0 0 0 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {margin:0in; margin-bottom:.0001pt; text-align:justify; font-size:12.0pt; font-family:Arial;} h1 {margin-top:12.0pt; margin-right:0in; margin-bottom:3.0pt; margin-left:0in; page-break-after:avoid; font-size:18.0pt; font-family:Arial;} h2 {margin-top:12.0pt; margin-right:0in; margin-bottom:3.0pt; margin-left:0in; text-align:justify; page-break-after:avoid; font-size:14.0pt; font-family:Arial;} h3 {margin-top:12.0pt; margin-right:0in; margin-bottom:6.0pt; margin-left:.25in; text-align:justify; text-indent:-.25in; page-break-after:avoid; font-size:13.0pt; font-family:Arial;} span.MsoLineNumber {color:#999999;} p.Code, li.Code, div.Code {margin:0in; margin-bottom:.0001pt; font-size:11.0pt; font-family:"Courier New"; color:black;} span.CodeChar {font-family:"Courier New"; color:black;} p.WorkComment, li.WorkComment, div.WorkComment {margin:0in; margin-bottom:.0001pt; text-align:justify; page-break-after:avoid; font-size:10.0pt; font-family:Arial; color:red; font-style:italic;} p.CodeCaption, li.CodeCaption, div.CodeCaption {margin-top:6.0pt; margin-right:0in; margin-bottom:0in; margin-left:.25in; margin-bottom:.0001pt; text-align:justify; page-break-after:avoid; font-size:12.0pt; font-family:"Courier New"; font-weight:bold;} p.CodeSpace, li.CodeSpace, div.CodeSpace {margin:0in; margin-bottom:.0001pt; font-size:8.0pt; font-family:"Courier New"; color:black;} p.HalfSpace, li.HalfSpace, div.HalfSpace {margin:0in; margin-bottom:.0001pt; text-align:justify; page-break-after:avoid; font-size:6.0pt; font-family:Arial;} span.CodeInline {font-family:"Courier New"; color:navy;} span.CodeKeyword {color:navy; font-weight:bold;} span.CodeString {color:blue;} p.Bullet1, li.Bullet1, div.Bullet1 {margin-top:0in; margin-right:0in; margin-bottom:0in; margin-left:.25in; margin-bottom:.0001pt; text-indent:-.25in; font-size:11.0pt; font-family:Arial;} span.CodeASPTag {color:purple;} p.QuarterSpace, li.QuarterSpace, div.QuarterSpace {margin:0in; margin-bottom:.0001pt; text-align:justify; font-size:3.0pt; font-family:Arial;} p.ByLine, li.ByLine, div.ByLine {margin:0in; margin-bottom:.0001pt; text-align:right; font-size:12.0pt; font-family:Arial; font-weight:bold;} @page Section1 {size:8.5in 11.0in; margin:1.0in 1.25in 1.0in 1.25in;} div.Section1 {page:Section1;} /* List Definitions */ ol {margin-bottom:0in;} ul {margin-bottom:0in;} --> </style>

Namespaces in Delphi 2005

To make Delphi code friendlier towards other .NET languages Borland has changed the way Delphi 2005 produces namespaces. This will make it easier for code written in other environments, like C# or Visual Basic, to use assemblies written in Delphi Pascal. The great thing is that Borland has done this without changing the language and all your previous code should still compile and run just as before. In fact, you normally do not even have to be concerned about namespace support in Delphi at all.

Executive Summary

Namespaces do not affect Delphi for Win32.

Namespaces are produced based on the unit name as follows:

If a unit name is dotted then the unit name up to the last dot is used.

If it is not dotted then the default namespace is used.

If there is no default namespace then the unit name is used.

Code converted from Delphi 8 may require some modifications.

Always use Packages not Libraries to create shareable assemblies.

Delphi will always refer to types by their full unit name.

Other languages will need to refer to types using their namespace.

ASP.NET declarations, configuration files and .NET reflection always refer to types by their namespace.

If multiple units emit a public type with the same name into the same namespace, the assembly may be unusable.

Since namespaces are a feature of .NET, this article is only applicable to the Delphi .NET personality and there is no change in the way you work with Win32 code.

Namespaces in Delphi 8

First, I will review how units and namespaces worked in Delphi 8. I am going to use these two simple source files as examples:

Sample.Controls.Base.pas

unit Sample.Controls.Base;

interface

type

TControl = class

end;

implementation

end.

Sample.Controls.Listview.pas

unit Sample.Controls.Listview;

interface

type

TListview = class(TControl)

end;

type

TItem = class

end;

implementation

end.

If you compile these into a package using Delphi 8 and look at the resulting assembly using a tool like Reflector you will see that it contains two namespaces: Sample.Controls.Base and Sample.Controls.Listview.

Open up the Sample.Controls.Base namespace and you will notice that it contains two classes. The first is the TControl class while the second is a class named Unit. This special class contains the initialization and finalization code for the Sample.Controls.Base unit as well as any procedures and functions defined at the unit level. Similarly, the Sample.Controls.Listview namespace contains the TListview and TItem classes as well as a Unit class for the Sample.Controls.Listview unit.

If you continue adding more units to the package, you will see that each unit gets its own unique namespace containing all the classes in the unit as well as an implementation of the Unit class.

So what was the problem?

Units are much easier to manage and maintain if there are only a few classes in each of them. However creating libraries with many units generates assemblies that contain a namespace for each unit. This is fine for Delphi programmers since the compiler hides the details of the assembly layout from us, but it is a problem for programmers who want to use our assemblies in other languages. C# programmers, for example, will have to import each namespace individually, making their code verbose and your library difficult to learn. If they want to use fully qualified names, then they will have to type something like Sample­.Con­trols­.Base­.TControl or Sample.Con­trols.Listview.­TList­view.

Namespaces in Delphi 2005

Load the package in Delphi 2005 and recompile it, then look at the resulting assembly again. You will notice that this time it looks slightly different. It now contains two namespaces Sample.Controls and Sample.Controls.Units.

If you take a closer look at the Sample.Controls namespace, you will see that it contains TControl, TListview and TItem. The compiler has placed all of the controls into a single namespace!

The Sample.Controls.Units namespace is similar and contains two classes Base and Listview. These are the special classes for each unit that we saw previously. Unlike with Delphi 8, adding more units will not add new namespaces.

This is much easier for other programmers to use. C# programmers can now type a single using statement to access all of the classes. For example, to access a class using its full name they can write Sample.­Controls.­TCon­trol.

Now add a third source file to the package:

Sample.Graphics.Screen.pas

unit Sample.Graphics.Screen;

interface

type

TScreen = class

end;

implementation

end.

You will see that the assembly now contains a Sample.Graphics namespace and a Sample.Graphics.Units namespace for the classes and unit we have just defined.

So where does the namespace come from?

The Delphi compiler looks at the name of each unit. If it is a dotted name then it will remove the part to the left of the last dot and use the left part as the namespace. In other words, a unit called Sample.Controls.Buttons will emit its classes in the Sample.­Controls namespace while a unit called Sample.­Controls.­Web.­DB.Grid will emit its classes into the Sample.­Controls.­Web.­DB namespace.

For unit names that do not contain a dot, the compiler will use the Default Namespace from the Project Options dialog:

Default Namespace Setting in Project 

Options Dialog

Lastly, if you there is no value for the default namespace then the compiler will simply use the unit’s name as the namespace. Therefore, a unit called Graphics will create a namespace with exactly the same name, Graphics.

Some Important Things to Remember

As with any change, there are times when the details can trip you up and you may get unusual errors. Here are three that you need to remember:

1) Always Use Packages

Borland has always recommended not using library projects to create assemblies. In Delphi 2005, the compiler is stricter and will no longer allow you to compile an application referencing a Delphi ‘library’.

Always use a package project to create .NET assemblies.

2) Referring to Types by their Fully Qualified Name

Most .NET languages require you to use the namespace to prefix types or as part of a namespace import (using) clause. However, Delphi will always use the unit name and never the namespace to qualify the type. This is true even if you add a reference to a third-party assembly created with Delphi as the compiler will detect this and use the appropriate unit names. (Note that when referring to assemblies created in other languages you should just use the namespace to qualify types.)

This mismatch often creates confusion. A common example is when using TypeConverters and Designers. For example given a type converter defined in a Delphi unit:

Sample.Controls.Design.pas

Type

TConverter = class(TypeConverter)

end;

To use this type converter you need to use the unit name to qualify the type:

Uses

Sample.Controls.Design;

type

[TypeConverter(typeof(TConverter))]

TItem = class

end;

or

Type

[TypeConverter(typeof(Sample.Controls.Design.TConverter))]

TItem = class

end;

Whereas the equivalent C# code would only require you to use the namespace as the prefix:

using Sample.Controls;

[TypeConverter(typeof(TConverter))]

class TListItem {

}

or

[TypeConverter(typeof(Sample.Controls.TConverter))]

class TListItem {

}

However, as with anything, there are exceptions to the rule and there are several situations where you need to use the namespace even though you are coding in Delphi.

One example is when you are using tags in ASPX, ASCX or ASMX files. If you create a web page called TWebForm in the file Application.­Pages.­WebForm1.­­pas then the page tag would be:

<%@Page Language="c#" Codebehind="WebForm1.pas" Inherits="Application.Pages.TWebForm1"%>

Another is when passing type information to .NET in the form of strings, especially when using reflection based APIs and configuration files:

var c:TypeConverter;

c:=Assembly.CreateInstance('Sample.Controls.TConverter');

This slight difference commonly trips people up and is something you need to be careful of, especially when porting code from Delphi 8 or converting code from other languages.

3) Duplicate Types

If we use the same name to define types in two units that have the same namespace then this creates a duplicate type, much like having two types in a single unit with the same name. As an example, add the following source file to the package:

Sample.Controls.Treeview.pas

unit Sample.Controls.Treeview;

interface

type

TTreeview = class(TControl)

end;

type

TItem = class

end;

implementation

end.

We now have two classes in our package called TItem, one in Sample.Controls.­List­view.­pas and the other in Sample.Controls.­Treeview.pas. If we look at the assembly using Reflector you will notice that the Sample.Controls namespace contains two types called TItem. This can occur not only for class types but also for any type supported by Delphi such as records and enumerations.

To avoid this problem, the compiler renames all types that are not visible from outside the assembly, in other words everything defined in the implement­ation section of a unit. It does this by appending the unit name to all internal types.

However if there are two public types in the same namespace with the same name then others might have problems using the assembly. A future release of the compiler should detect this situation. In the meantime I recommend checking your executables and assemblies using the peverify tool that ships with the .NET SDK as part of your testing.

Porting Code from Delphi 8

You can generally port Delphi 8 to Delphi 2005 without making any changes; however, you should consider the above issues when doing so.

Here are some things you may want to check for:

Convert library projects to packages unless you are using unmanaged exports.

Check namespaces used in code, especially in reflection and configuration files.

The IDE should convert ASPX Tags for you but it is always worth checking them.

Check your assemblies for duplicate types using peverify.

Summary

Once you understand how Delphi generates namespaces, Delphi’s support for them is logical, flexible and very easy to use, without changing the language. So much so that you will never even know it is there until you need it. Nevertheless, it makes Delphi assemblies far easier to use for other coders.

The most important point to remember is that a namespace and a unit name are no longer the same thing. Delphi always uses unit names.

About the Author

Marc Rohloff occupies himself doing pretty much anything related to IT. He currently specializes in .NET technologies and is a member of TeamB. He has worked in many odd corners of the world, the current one being in Columbus, Ohio where he is on contract as a Delphi Mentor. You can contact Marc at marc2005 <script language="JavaScript">document.write('@');</script> @<noscript>­@&amp;shy</noscript>bigfoot.com .


转自:
http://bdn.borland.com/article/0,1410,32765,00.html
分享到:
评论

相关推荐

    [done]Rooting out Root User namespaces in Docker.pdf

    [done]Rooting out Root User namespaces in Docker.pdf

    Namespaces

    在XML 1.0规范中并没有直接涉及Namespaces的定义,而是通过《Namespaces in XML》这个独立的推荐标准来详细阐述。该标准由W3C在1999年1月14日发布,并对XML家族中的其他规范如XHTML、XSL、XSLT、XML Schema和XML ...

    Delphi for .NET Developer's Guide

    Delphi for .NET Developer's Guide is a new edition of the #1 Delphi book by authors Xavier Pacheco and Steve Teixeira. This newest edition is completely updated for Delphi using the .NET Framework ...

    delphi中的脚本控件paxscript3.0

    TPaxScripter for Delphi 5, 6, 7, 2005, BCB 5, BCB 6, Kylix 3. ------------------------------------------------------------------------------ Version: 3.0. Build: 29 May, 2006. Copyright (c) 2003-2006 ...

    从Delphi转C#初学Demo.zip

    1. 类型系统与命名空间:Delphi中的类型系统与C#相似,但C#引入了命名空间(Namespaces)的概念,用于组织代码。在Delphi中,我们通常使用单元(Units)来管理代码,而在C#中,我们需要导入相应的命名空间来使用类库...

    Namespaces and cgroups

    ● Usage of namespaces and cgroups in other projects. ● Is process virtualization indeed lightweight comparing to Os virtualization ? ●Comparing to VMWare/qemu/scaleMP or even to Xen/KVM.

    [done]Cgroups and Namespaces.pdf

    [done]Cgroups and Namespaces.pdf

    DELPHI与C#语法比较.docx

    - C#的foreach循环可方便地遍历数组或集合,DELPHI则使用`for...in`类似功能。 7. 类和接口(Classes / Interfaces): - 两者都支持类和接口,但C#的接口更灵活,可以包含默认实现。 - DELPHI的类支持多重继承...

    17-namespaces.rar

    在Linux和UNIX系统中,namespaces是实现进程隔离和资源管理的一种重要机制。它允许不同进程看到不同的全局命名空间,比如文件系统、网络接口、进程ID等,从而达到虚拟化的效果,让每个进程都认为自己拥有独立的环境...

    xml delphi

    XML(eXtensible Markup Language)是一种用于标记数据的语言,它在软件开发中扮演着重要的角色,特别是在Delphi编程环境中。Delphi是Embarcadero Technologies公司开发的一种面向对象的 Pascal 编程语言,它拥有...

    Python库 | class_namespaces-0.3.6-py3-none-any.whl

    《Python库class_namespaces-0.3.6-py3-none-any.whl详解》 在Python的世界里,库是开发者的重要工具,它们提供了丰富的功能,让编程变得更加简单和高效。今天我们将聚焦于一个名为"class_namespaces"的Python库,...

    web-namespaces:Web名称空间地图

    npm install web-namespaces 用 import { webNamespaces } from 'web-namespaces' console . log ( webNamespaces ) 产量: { html : 'http://www.w3.org/1999/xhtml' , mathml : '...

    NET 3.5 Namespaces Poster LORES

    标题与描述中的“NET 3.5 Namespaces Poster LORES”指向了Microsoft .NET Framework 3.5中广泛使用的类型和命名空间。这份文档旨在为软件开发者提供一个全面且易于理解的指南,帮助他们掌握.NET Framework的核心...

    源码 Dr.Bob’s Delphi Prism XE Development Essentials June 2011

    Delphi Prism Projects and Namespaces 9 Methods ... 11 Unnamed Constructors ............................................................. 12 IDE: Build and Debug ..........................................

    NET Windows Forms in a Nutshell

    The second half is a quick reference to the Windows Forms and GDI+ namespaces. It provides namespace maps, type descriptions, member signatures, and useful cross-references and annotations.

    Dot NET Framework 4 Namespaces Poster

    总的来说,.NET Framework 4 Namespaces Poster是一份宝贵的参考资料,它为开发者提供了一目了然的视图,有助于深入理解和使用.NET Framework 4的庞大类库。不论你是初学者还是经验丰富的开发者,都应该将其作为日常...

    JavaScript权威指南 第五版

    This Fifth Edition is completely revised and ...Namespaces in JavaScript--essential when writing complex programs Classes, closures, persistence, Flash, and JavaScript embedded in Java applications

    JavaScript.The.Definitive.Guide

    This Fifth Edition is completely revised and ...Namespaces in JavaScript--essential when writing complex programs Classes, closures, persistence, Flash, and JavaScript embedded in Java applications

    java谜题解惑 中文版.rar

    java谜题解惑This Fifth Edition is completely ...Namespaces in JavaScript--essential when writing complex programs Classes, closures, persistence, Flash, and JavaScript embedded in Java applications

    Professional C++, 4th Edition

    By 作者: Marc Gregoire ISBN-10 书号: 1119421306 ISBN-13 书号: 9781119421306 Edition 版本: 4 出版日期: 2018-04-17 pages 页数: 1176 内容简介: Get up to date quickly on the new changes coming with C++...

Global site tag (gtag.js) - Google Analytics