Confusion
There seems to be a big confusion about Delphi for .NET namespaces. I guess this is because there was a big change between Delphi 8 and Delphi 2005.
In Delphi 8, each unit was its own namespace. In Delphi 2005, several units can be placed in the same namespace, by prefixing the unit name with the namespace name. You can even add to an existing namespace in an assembly not written in Delphi for .NET.
I often see the argument that namespaces in Delphi for .NET are non-standard. But since you can create a namespace consisting of several units, in several assemblies, there is in fact no big difference for other .NET languages. To the "outside" world, i.e. to non-Delphi code, they are as standard as they should be.
IOW, if you have units Rudy.Velthuis.Labels, Rudy.Velthuis.EditBoxes, and Rudy.Velthuis.Memos they make up the namespace Rudy.Velthuis, and can be used as such from any non- Delphi .NET language. (FWIW, if your namespace is only meant to contain VCL.NET classes, I see no reason not to use the VCL terminology, i.e. prefix types with T, etc. If your assembly is meant to be used by other languages, then follow the .NET guidelines on naming.)
What is different is that Delphi for .NET internally has the advantage that you don’t include an entire namespace, filling up the scope with a lot of unnecessary identifiers, but only the units you need. This is IMO a big advantage. If you only need Labels, but not EditBoxes or Memos, you only put Rudy.Velthuis.Labels in your uses clause. I’ll explain why this is IMO a Good Thing™
Any good C++ programmer will frown upon the practice of including entire namespaces into the scope. A good C++ programmer will not use
using namespace std;
but will simply qualify each identifier from that namespace with the explicit std:: prefix. For the same reason, Modula 2 users can import entire modules, but are encouraged to only import the identifiers they need. Delphi for .NET’s scope resolution is not that fine grained, but at least it offers units, instead of the inclusion of entire namespaces. Of course this only works with Delphi-written namespaces.
The fact that namespaces are disconnected from physical file names is perhaps not a problem for a compiler (well, it actually is a small problem, since it makes it have to look up and remember — store — a lot more identifiers, which makes it slower), but it is a problem for the humans who have to use them. I am glad that Delphi keeps the connection between compilation unit and logical unit.
Conclusion
So, to recap:
- Delphi namespaces are extensible, like in other .NET languages. Several units can make up a namespace, and units can be added to one. They are perhaps non-standard internally, but to the outside .NET world, they are no different than a VB or C# namespace.
- Delphi namespaces are usable by other languages as one namespace, no matter how many units it contains.
- Internally, when Delphi uses Delphi-written namespaces, Delphi has the added advantage that you don’t have to include entire namespaces at once, but have a finer grained scoping mechanism.
- Delphi units are IMO easier to use than namespaces consisting of several source files and spread over several assemblies.
Rudy Velthuis
{ 6 } Comments
/me puts in a vote for Modula-2 namespace handling.
Actually I M2ed a while before returning to Pascal (then still TP), but that choice was more based on the compiler than the language.
Inner modules and the import behaviour are still the nice parts of M2.
Good post! There seem to be indeed some misunderstandings about namespaces out there - not just in the Delphi world ;-)
Anyway, there are two things which may lead to confusion in Delphi.NET:
1: Delphi always emits an *additional* implicit "Units" name space. If you have a unit "Foo.Bar.Test.pas" containing a class "Test" Then you will see a name space "Foo.Bar" as expected, but also a name space Foo.Bar.Units, also containing a class "Test".
This is not just an "alias", in fact Delphi will mark any class in these "Units" name spaces as "sealed", and these classes appear incomplete (no constructors, etc). In other words this is just some "magic", used by Delphi only. In other .NET languages you should not touch these "Units" namespaces.
2: Error Insight (at least on my machine) does not like stuff like this:
unit Foo.Bar.Class1;
…
end;
unit Foo.Bar.Class2;
interface
…
implementation
uses Class1;
…
This will compile fine, but "uses Class1" will be underlined in red. Errorinsight only likes the full reference - no matter what’s defined as Default Namespace:
unit Foo.Bar.Class2;
interface
…
implementation
uses Foo.Bar.Class1;
…
Actually discard #2 - it’s been a compiler error ….
This just leaves #1 - the "mysterious Units" namespace - which make Delphi assemblies look weird to non-Delphi users. They just have to ignore it, as everything else works fine.
AFAIK, the Units subnamespace is the namespace binding non-method functions and procedures in Delphi to .NET classes. There is no way to get rid of it, and I personally don’t see it as a problem. It may look weird in Reflector, but Reflector is not .NET, it is only a tool for it.
I don’t see a technical problem either with the "Units" subnamespace. It’s purely cosmetic - IMO.
Hello,
Sorry for posting off topic here, I just can’t find direct mail or other communication channel at your site.
In your article you have mentioned a possible solution to CRTL external functions problem by declaring them as external in msvcrt.dll I’ve found another way how to solve this problem- extract all OBJ files directly from BCB55’s cw32.lib file using tlib as a helper tool. __ftol and _ftol are in ftol.obj This way I was able to bind sqlite3.lib directly into my Delphi project without DLL file (81 obj files, the order of $L is important) The only unresolved external is _wsprintfA wich is in user32.dll
Post a Comment