Namespaces

 
Chapter 2 - C# Basics
bySimon Robinsonet al.
Wrox Press 2002
  

As we have seen earlier, namespaces provide a way of organizing related classes and other types. Unlike a file or a component, a namespace is a logical, rather than a physical grouping. When we define a class in a C# file, we can include it within a namespace definition. Later, when we define another class that performs related work in another file, we can include it within the same namespace, creating a logical grouping that gives an indication to other developers using the classes how they are related and used:

   namespace CustomerPhoneBookApp     {     using System;     public struct Subscriber     {     // Code for struct here...     }     }   

Placing a type in a namespace effectively gives that type a long name , consisting of the type's namespace as a series of names separated with periods ( . ), terminating with the name of the class. In the example above, the full name of the Subscriber struct is CustomerPhoneBookApp.Subscriber . This allows distinct classes with the same short name to be used within the same program without ambiguity.

We can also nest namespaces within other namespaces, creating a hierarchical structure for our types:

   namespace Wrox     {     namespace ProCSharp     {     namespace Basics     {     class NamespaceExample     {     // Code for the class here...     }     }     }     }   

Each namespace name is composed of the names of the namespaces it resides within, separated with periods, starting with the outermost namespace and ending with its own short name. So the full name for the ProCSharp namespace is Wrox.ProCSharp , and the full name of our NamespaceExample class is Wrox.ProCSharp.Basics.NamespaceExample .

We can use this syntax to organize the namespaces in our namespace definitions too, so the code above could also be written:

   namespace Wrox.ProCSharp.Basics     {     class NamespaceExample     {     // Code for the class here...     }     }   

Note that we are not permitted to declare a multi-part namespace nested within another namespace.

Namespaces are not related to assemblies. It is perfectly acceptable to have different namespaces in the same assembly, or define types in the same namespace in different assemblies.

The using Statement

Obviously, namespaces can grow rather long and tiresome to type, and the ability to indicate a particular class with such specificity may not always be necessary. Fortunately, as we noted at the beginning of the chapter, C# allows us to abbreviate a class's full name. To do this, we list the class's namespace at the top of the file, prefixed with the using keyword. Throughout the rest of the file, we can refer to the types in the namespace simply by their type names.

If two namespaces referenced by using statements contain a type of the same name, then we will have to use the full (or at least, a longer) form of the name to ensure that the compiler knows which type is to be accessed. For example, say classes called NamespaceExample exist both in the Wrox.ProCSharp.Basics and Wrox.ProCSharp.OOP namespaces. If we then create a class called Test in the Wrox.ProCSharp namespace, and instantiate one of the NamespaceExample classes in this class, we need to specify which of these two classes we're talking about:

   using Wrox.ProCSharp;     class Test     {     public static int Main()     {     Basics.NamespaceExample NSEx = new Basics.NamespaceExample();     return 0;     }     }   

You will have noticed that we have been adding the using System; statement to the start of most of our examples. You will find that the vast majority of all C# code does the same, since the CTS types mentioned earlier are all contained within this namespace, as is much of .NET's core functionality, such as console I/O.

Since using statements occur at the top of C# files, in the same place that C and C++ list #include statements, namespaces are often confused with header files. Don't make this mistake. The using statement does no physical linking between files.

Your organization will probably want to spend some time developing a namespace schema so that its developers can quickly locate functionality that they need and so that the names of the organization's homegrown classes won't conflict with those in off-the-shelf class libraries. You can refer to Microsoft's .NET SDK documentation for guidelines on establishing your own namespace scheme.

Namespace Aliases

Another use of the using keyword is to assign aliases to classes and namespaces. If we have a very long namespace name that we want to refer to several times in our code, but don't want to include in a simple using statement (for example, to avoid type name conflicts), we can assign an alias to the namespace. The syntax for this is:

 using  alias  =  NamespaceName;  

The following example (a modified version of the previous example) assigns the alias Introduction to the Wrox.ProCSharp.Basics namespace, and uses this to instantiate a NamespaceExample object, which is defined in this namespace. This object has one method, GetNamespace() , which uses the GetType() method exposed by every class to access a Type object representing the class's type. We use this object to return a name of the class's namespace:

   using System;     using Introduction = Wrox.ProCSharp.Basics;   class Test {    public static int Main()    {       Introduction.NamespaceExample NSEx =          new Introduction.NamespaceExample();   Console.WriteLine(NSEx.GetNamespace());   return 0;    } }   namespace Wrox.ProCSharp.Basics     {     class NamespaceExample     {     public string GetNamespace()     {     return this.GetType().Namespace;     }     }     }   
  


Professional C#. 2nd Edition
Performance Consulting: A Practical Guide for HR and Learning Professionals
ISBN: 1576754359
EAN: 2147483647
Year: 2002
Pages: 244

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net