So what exactly is going to be covered in this article? VB.NET namespaces and C# namespaces? Aren’t they the same thing?
From namespaces perspective, VB.NET and C# have pretty same concepts and syntaxes such as period as delimiters, being placed outmost, and so on (with slightly differences though, e.g. keywords being capitalized, ending syntaxes necessary, and something like that in VB.NET); but from the root vs. default namespace perspective regarding VB.NET and C#, things are quite different and confuse people all the time.
For programmers mainly specialized in only VB.NET or C#, the differences may not be so critical; but for people who frequently use both languages and especially build some bridges between the two, it is obviously very important to keep in mind of the differences.
Ok, now what is really different between the VB.NET Root Namespace and C# Default Namespace? And where these terms come from actually?
They come from the Application setting page of Project Properties of C# projects and VB.NET ones. For example, if we create a C# project and name it as NamespacesCS, its Default Namespace will be defaulted as NamespacesCS as well, the same as the project name and the assembly name.
If we create a VB.NET project and name it as NamespacesVB, its Root Namespace will be defaulted as NamespacesVB as well, the same as the project name and the assembly name again.
So the same place to find both of them and the same naming pattern for the default names of C# Default Namespace and VB Root Namespace. Then what is the big fuss here?
Right, the fuss is not with the naming pattern or the place of the two terms; rather, it is with how they affect coding and finally the class/interface/type trees in the resultant C# and VB.NET assemblies.
Let’s us check on this in more detail with some coding examples. First, we define a very simple class into the C# project, name it as ClassTest, and add an introduction method to it:
public class ClassTest
public String Introduction()
return "Hi, I am the ClassTest with full name " + this.GetType().FullName;
Next, we follow the same coding style, create a class with the same name, and add the same method to the VB.NET project:
Public Class ClassTest
Public Function Introduction() As String
Return "Hi, I am the ClassTest with full name " & Me.GetType().FullName
Now both of them should compile and build just well.
We create a test project of Windows Application type for both of them, name it as TestNamespeces and reference both the C# and VB.NET projects in:
Now add a button to the default Windows Form and implement its callback like:
private void button1_Click(object sender, EventArgs e)
string msg = string.Empty;
NamespacesCS.ClassTest csClassTest = new NamespacesCS.ClassTest();
msg += csClassTest.Introduction() + Environment.NewLine;
NamespacesVB.NamespacesVB.ClassTest vbClassTest = new NamespacesVB.NamespacesVB.ClassTest();
msg += vbClassTest.Introduction() + Environment.NewLine;
Keen readers may have already noticed that the VB.NET class, ClassTest, has to be qualified with two NamespacesVB namespaces. That is the fuss actually!
The introduction of the two classes make things clearer:
So a VB.NET project addes a default namespace to all its types as specified by the Root Namespace in the Application page of the Project Properties window. That may also explain why the VB.NET Class Library wizard does not add any namespaces for its auto-generated classes. The ‘Root’ here means a few extra things, default and mandatory, in case something is given as the Root Namespace, which is defaultly true for projects created by Visual Studio wizards.
So we should either follow the same coding style, skipping the namespaces in code, or do something about it. The good thing is that if we want the same coding style as C#, there is no problem at all. Blanking the Root Namespace from the same UI makes things easily done.
A C# project will not use the specified Default Namespace as some implicit outmost namespace. Rather, its item wizards such as the Class Library one will add the namespace to the new types automatically in some explicit code as demonstrated earlier. It lacks some in-box behavior but increases flexibility a lot, and better, does not increase any labor to programmers.
If the difference still does not seem to matter at all, let’s do another simple experiment, to access the same type in the SAME module as the type definition is:
Public Class TestClassTest
Public Shared Sub AccessToItInTheSameModule()
Dim clsTest As NamespacesVB.NamespacesVB.ClassTest = New NamespacesVB.NamespacesVB.ClassTest()
The following will be complained about if the code is being compiled:
“Error 1 Type 'NamespacesVB.NamespacesVB.ClassTest' is not defined.”
Removing one NamespacesVB qualifier would resolve the issue.
But what? Different signatures in different places for exactly the same type?!?!
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) keeps the same coding style for VB.NET projects it creates automatically, indicating the Root Namespace of the VB.NET projects will be set as empty and the project name instead will be used as the default namespace.