Using Namespaces

There are some subtle differences in how C++ and C# handle namespaces and scope. I have had a few people ask me about it so I thought I would talk about it here. First the basics: a namespace allows you to group names in your program together to provide some context for them and to avoid conflicts with names declared in other namespaces. How you actually make use of names and namespaces in C++ and C# differ quite a bit.

Explicit Qualification

Consider the name Console declared in the namespace System.

In C++ the namespace member can be accessed using explicit qualification using the scope resolution operator:

System::Console

In C# the same can be accomplished with the period token:

System.Console

The difference here is merely syntactic sugar. The main difference is that C# uses the period for explicit qualification of names as well as for member access. C++ uses the scope resolution operator for declaring the scope of a name and uses the member access operators (. and ->) for referring to members of classes and structures.

That is where the behavioral similarities of namespaces in C++ and C# end.

Using Directive

A using directive allows the names in a namespace to be used without explicit qualification. In C++ you write a using directive as follows:

using namespace System;

This allows me to use Console without the qualifier. All the names declared in the namespace are now available. This includes nested namespace. For example since System has a nested namespace called IO that declares a name, FileStream, you can access FileStream as follows:

IO::FileStream

This is in contrast to C#’s using directive which only permits the types in a namespace to be accessed and does not bring forward any nested namespaces. In C# you write a using directive as follows:

using System;

If you wanted to access FileStream you would need to either use explicit qualification or add yet another using directive for the nested namespace:

using System.IO;

In this area I much prefer the C++ rules as I can write a using directive for the ubiquitous System namespace and use all manner of names and nested names without polluting the global namespace too much:

using namespace System;

int main()
{
    String^ string;
    IO::FileStream stream;
    Net::NetworkCredential^ credentials;
}

In C# it is more common (and popularized by Visual C#) to simply flood the global namespace with all the necessary types:

using System;
using System.IO;
using System.Net;

class Program
{
    static void Main()
    {
        String string1;
        FileStream stream;
        NetworkCredential credentials;
    }
}

The problem here of course is that we now face the problem namespaces were originally designed to solve: name collisions.

Alias

There are of course a few alternatives to using directives. In C++ you can use the typedef specifier to declare a new name for an existing type. The new name and the original name are interchangeable at compile-time (think templates) and runtime:

using namespace System;
typedef Runtime::Serialization::Formatters::Binary::BinaryFormatter Formatter;

int main()
{
    Formatter^ formatter;
}

C# allows you to create an alias with the using directive. An alias can be created for both namespaces and types:

using Formatter = System.Runtime.Serialization.Formatters.Binary.BinaryFormatter;

class Program
{
    static void Main()
    {
        Formatter formatter;
    }
}

C++ also offers the ability to introduce a name from a different name space without creating an alias per se:

using namespace System;
using Runtime::Serialization::Formatters::Binary::BinaryFormatter;

int main()
{
    BinaryFormatter^ formatter;
}

Hopefully this summary will help to clear up some confusion among developers moving between C++ and C#. This is certainly not a complete description of namespaces, but it covers the main usage patterns and differences that developers are likely to come across.


© 2004 Kenny Kerr

 

No Comments