DN4DP#17: .NET only: Multi-unit namespaces
This post continues the series of The Delphi Language Chapter teasers from Jon Shemitz’ .NET 2.0 for Delphi Programmers book.
The previous post covered platform differences for floating-point semantics. This time we'll look at namespace support.
Note that I do not get any royalties from the book and I highly recommend that you get your own copy – for instance at Amazon.
"Multi-unit namespaces
With the trinity of a logical unit concept, physical unit source .pas files and compiled .dcu files, Delphi has always had a very efficient and useful module concept. To address the hierarchal namespace support required in .NET while still being backwards compatible, Delphi 8 introduced the concept of dotted unit names, such as Borland.Vcl.SysUtils and Borland.Vcl.Classes - these unit names were mapped directly to .NET namespaces.
This was a step in the right direction, but Delphi 2005 extended this concept to allow multiple Delphi units to contribute to the same logical namespace. Now the namespace of a dotted unit name is everything up to the last dot.
So now both the SysUtils and Classes units reside in a single Borland.Vcl namespace. This allows the programmer to split his code into multiple physical units, while exposing the contained classes in a single logical namespace. This makes it easier and more convenient to write assemblies that can be used by other languages (such as C#).
unit MultiUnit.Namespaces.Unit2;
...
class procedure TBar2.Foo;
begin
Writeln(TBar2.ClassInfo.ToString, '.Foo');
end;
The code above writes the fully qualified namespace of the TBar2 type, and the output is MultiUnit.Namespaces.TBar2.Foo in this case.
unit MultiUnit.Namespaces.Unit1;
interface
type
TBar1 = class
class procedure Foo; static;
end;
procedure Test;
implementation
class procedure TBar1.Foo;
begin
{$IFDEF CLR}
Writeln(TBar1.ClassInfo.ToString, '.Foo');
{$ELSE}
Writeln(TBar1.ClassName, '.Foo');
{$ENDIF}
end;
procedure Test;
begin
TBar1.Foo;
end;
end.
unit MultiUnit.Namespaces.Unit2;
interface
type
TBar2 = class
class procedure Foo; static;
end;
implementation
class procedure TBar2.Foo;
begin
Writeln(TBar2.ClassInfo.ToString, '.Foo');
end;
end.
unit MultiUnit.Namespaces.Unit3;
interface
procedure Test;
implementation
uses
MultiUnit.Namespaces.Unit1,
MultiUnit.Namespaces.Unit2;
procedure Test;
begin
Writeln('Note that even though TBar1 and TBar2 are in separate Delphi units');
Writeln('they reside in the same namespace (MultiUnit.Namespaces)');
TBar1.Foo;
TBar2.Foo;
end;
end.
"
No comments:
Post a Comment