Namespaces in C# vs. VB.NET

Mike_R

Junior Contributor
Joined
Oct 20, 2003
Messages
316
Location
NYC
Hi guys,

I have recently switched over my coding from VB.NET to C#. Overall, everything is just fine. However, I'm a little puzzled over how namespaces work in C#. I have heard that they are much better, but best I can tell they simply seem stricter. (Or is this why they are better?)

The two things that I've noticed are:

(1) You cannot import a class (type) name as part of a 'using' import. This is not a big deal, but it does let VB.NET access enum fields directly without requiring the enum type name as a prefix. This is nice. On the other hand, this would allow any static method to be called without the type name. This could be good in that you could create methods that look like keywords (you can do this in VB), but I can also see why C# would want to prevent this.

(2) You cannot seem to import a partial-name. This part is what I'm most confused about. For example, in VB I can import 'System.Windows' and then later can call 'Forms.MessageBox.Show("foo")'. In C# however, it seems a bit more all-or-nothing. I cannot imports 'System.Windows'; it seems that I can either import 'System.Windows.Forms' as a whole, or not at all.

In general, it seems that if the namespace only contains other namespaces, but no types, I cannot import it -- I can only import a full path to a namespace that does contain at least one type. Or am I doing something wrong?

Any thoughts or help here is much appreciated...

Mike
 
Importing empty namespaces?

Thoughts...

As for importing namespaces which don't contain any types, personally I can't see why you'd want to do this. On the one hand you say you like being able to access static methods and enumeration values without specifying the containing type, but on the other you're suggesting you like having to prefix everything with Forms. That said, you should be able to recreate this:

C#:
using Forms = System.Windows.Forms;

Again it all comes down to style, and what you are used to. I've never heard that C#'s handling of namespaces is considered better than VB's, and it seems like a strange claim to make.
 
Re: Importing empty namespaces?

Hey MrPaul,

Thanks for your thoughts, they were good ones.

Thoughts...

As for importing namespaces which don't contain any types, personally I can't see why you'd want to do this. On the one hand you say you like being able to access static methods and enumeration values without specifying the containing type, but on the other you're suggesting you like having to prefix everything with Forms.
Yeah, I guess I didn't give a very good example there. It certainly wasn't practical.

A more practical example is when you have, say, two or more assemblies, whose names use the standard CompanyName.TechnologyName naming convention. For example, "Microsoft.Win32" or whatever. In this situation, I would like to import the 'CompanyName' namepace so that I can directly access the next level (which tends to have shorter names).

That said, you should be able to recreate this:

C#:
using Forms = System.Windows.Forms;

Again it all comes down to style, and what you are used to.
Ah, yes, thank you! This is exactly what I was looking for. Much thanks.

I've never heard that C#'s handling of namespaces is considered better than VB's, and it seems like a strange claim to make.
I have. More than once. The most recent time I saw it was from an experienced C# programmer. It's in a private forum, or I'd give a link. It did make me curious. Best I can tell they do seem almost identical.

Thanks for getting me unstuck on this though. It's very much appreciated...

Mike
 
Re: Importing empty namespaces?

Ok, I thought of a small, but nice advantage that C# namespaces have: you can use the using statement within a namespace, instead of being for the entire project or entire document. This is better encapsulation and certainly makes it more portable as well, if you need to move a namespace out of the document into another document or project.

Still, they do seem to be extremely similar overall...
 
I must admit I've never wanted to import a classname other than when I first moved to .Net from VB6 - i find the classname.methodname syntax far clearer to read than just having functions imported into a global namespace.

The ability to import partial namespaces and / or classnames can cause problems in the long run as the code you are writing now isn't guaranteed to be non-ambiguous in the future...

Currently if I was to import the System.Windows.Forms.MessageBox class I could call the Show method directly (only as an example - again I would find this code very awkward to read at a later date), I could also be doing the same with other classes which do not have a Show method in this version. At a later date when I come to do further maintenance of my code I could now be linking against a different version of one of these other libraries which in this new version include a Show method. This is now going to cause compile time errors and require further (possibly extensive) code modifications (plus testing etc.) to fix.

Partial namespaces are also susceptible to the same problem if an existing library adds an additional namespace in a future version.

Note that namespaces are a compile time nicety and do not affect the resultant IL code so no existing binaries will be affected - it's just the potential maintenance nightmare that could happen if we ever need to fix / recompile existing code (not that this ever happens much :rolleyes:)

I personally just import common namespaces without aliasing them (system, system.data, system.io, system.xml and the like) - it is unlikely a 3rd party will write code that clashes with anything in them plus I use them frequently enough to be familiar with them and their contents. Most other namespaces I tend to import and alias to a few standard abbreviations - this way I keep the advantage of short namespaces (I can't imagine anyone typing System.Runtime.Serialisation.Formatters.BinaryFormatter on a regular basis) but also enforce a uniqueness that should prevent name clashes in the future.
 
Hey PD,

Thanks for your thoughts. I agree with everything you said here. Although, I think there can be another aspect to some of them...

PlausiblyDamp said:
I must admit I've never wanted to import a classname other than when I first moved to .Net from VB6 - i find the classname.methodname syntax far clearer to read than just having functions imported into a global namespace.
I agree here and this might be the case for me since I am only just now moving from VB.NET to C#. For methods, I agree 100% that 'ClassName.MethodName' is much clearer and safer. However, I would personally not mind an exception whereby Enum types were allowed to be imported, allowing calls to show the Enum field name without having to utilize the 'EnumType.EnumFieldName' construct always. This is only a minor annyance however, but is an area where VB.NET code does look nicer.

The ability to import partial namespaces and / or classnames can cause problems in the long run as the code you are writing now isn't guaranteed to be non-ambiguous in the future...

Currently if I was to import the System.Windows.Forms.MessageBox class I could call the Show method directly...
Agreed. But I think the bigger issue is that method calls should not be divorced from the containing type, as you stated above.

Partial namespaces are also susceptible to the same problem if an existing library adds an additional namespace in a future version.
Yes, true. But this can currenly occur with a newly-introduced type. So method name and namespace name clashes cannot occur in future versions using C#, but a type-name collision could happen. So C# is safer than VB on this mark, but not immune.

The reason that I wanted to be able to import a Namespace that did not contain any types, was so that I could simplify namespaces such as the following:
Code:
    AcmeProgramming.AcmeBase
    AcmeProgramming.AcmeMidTier
    AcmeProgramming.AcmeUserIO

Using VB.NET I can shorten the lengthes of all three of these in one shot:
Visual Basic:
Imports AcmeProgramming

And now I can just call 'AcmeBase' or 'AcmeMidTier', etc., directly. However, I was suprised to find that C# did not let me do this. But MrPaul pointed out the solution, above:
Code:
using AcmeBase = AcmeProgramming.AcmeBase
using AcmeMidTier = AcmeProgramming.AcmeMidTier
using AcmeUserIO = AcmeProgramming.AcmeUserIO

Note that namespaces are a compile time nicety and do not affect the resultant IL code so no existing binaries will be affected - it's just the potential maintenance nightmare that could happen if we ever need to fix / recompile existing code (not that this ever happens much :rolleyes:)
I've not seen this yet, but I doubt it would be *too* hard to disambiguate? Best would be if the compiler error stated the full namespace path to the types which could be viable. If not, then yeah, might have to go back to an earlier version and compare. Not fun :(

Thanks PD,
Mike
 
Back
Top