O’Reilly Media, Inc. 3/13/2012
The file begins with a series of using directives. These are optional, but almost all source
files contain them, and they tell the compiler which namespaces we’d like to use, raising
the obvious question: what’s a namespace?
Namespaces
Namespaces bring order and structure to what would otherwise be a horrible mess. The
.NET Framework class library contains over 10,000 classes, and there are many more
classes out there in 3
rd
party libraries, not to mention the classes you will write yourself.
There are two problems that can occur when dealing with this many named entities. First,
it becomes hard to guarantee uniqueness unless everything either has a very long name,
or the names include sections of random gibberish. Second, it can become challenging to
discover the API you need—unless you know or can guess the right name, it’s difficult to
find what you need from an unstructured list of thousands of things. Namespaces solve
both of these problems.
Most .NET types are defined in a namespace. Microsoft-supplied types have distinctive
namespaces. When the types are part of the .NET Framework, the containing namespaces
start with System, and when they’re part of some Microsoft technology which is not a
core part of .NET, they usually begin with Microsoft. Libraries from other vendors
tend to start with the company name, while open source libraries often use their project
name. You are not forced to put your own types into namespaces, but it’s recommended
that you do. C# does not treat System as a special namespace, so nothing stops you
using that for your own types, but it’s a bad idea because it will tend to confuse other
developers. You should pick something more distinctive for your own code, such as your
company or project name.
The namespace usually gives a clue as to the purpose of the type. For example, all the
types that relate to file handling can be found in the System.IO namespace, while those
concerned with networking are under System.Net. Namespaces can form a hierarchy.
So the framework’s System namespace doesn’t just contain types. It also holds other
namespaces, such as System.Net, and these often contain yet more namespaces, such
as System.Net.Sockets and System.Net.Mail. These examples show that
namespaces act as a sort of description, which can help you navigate the library. If you
were looking for regular expression handling, for example, you might look through the
available namespaces, and notice the System.Text namespace. Looking in there,
you’d find a System.Text.RegularExpressions namespace, at which point
you’d be pretty confident that you were looking in the right place.
Namespaces also provide a way to ensure uniqueness. The namespace in which a type is
defined is part of that type’s full name. This lets libraries use short, simple names for
things. For example, the regular expression API includes a Capture class representing
the results from a regular expression capture. If you are working on software that deals
with images, the term ‘capture’ is more commonly used to mean the acquisition of some
image data, and you might feel that Capture is the most descriptive name for a class in
your own code. It would be annoying to have to pick a different name just because the
best one is already taken, particularly if your image acquisition code has no use for
regular expressions, meaning that you weren’t even planning to use that Capture type.
But in fact it’s fine. Both types can be called Capture, and they will still have different
names. The full name of the regular expression capture class is effectively
System.Text.RegularExpressions.Capture, and likewise your class’s full
18