Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C# (http://www.go4expert.com/articles/c-sharp-tutorials/)
-   -   Understanding Namespaces in C# With Examples (http://www.go4expert.com/articles/understanding-namespaces-c-sharp-t29989/)

usmanmalik 3Feb2014 07:38

Understanding Namespaces in C# With Examples
 
C# and Java are object oriented language where all code resides in a .NET type called class. An object oriented languages are those languages where user defined code has to be in some class. C# is 99.9% object oriented. You must be wondering why not 100%? The reason is that primitive data types in C# are not considered objects; they are considered simple data types. However they can be treated as objects as they have several functions and attributes associated with them as well. But conventionally, they do not fall in the class category. All your code exists inside a class which in turn exists in a broader category known as the namespace.

What is a namespace?



Code organization has always been on the top of priority lists of most of the programmer as organization results in more maintainable, manageable and reusable code. Object oriented programming paradigm was introduced in order to suffice the organization needs of code. However, embedding code inside a class was not enough because there can be thousands of classes. Managing a long list of classes without any intermediate organization mechanism is extremely laborious task which is also prone to errors. Therefore in order to a high level organizational entity was introduced in most of the advanced programming languages. In .NET frame work, namespace was introduced for this purpose.

Namespace is basically a high level entity which contains different classes that are related to each other. .NET framework class library that is shipped with the .NET framework contains thousands of classes. Without namespace it would be extremely messy and meticulous coding and referring strategy would have been required to properly import classes to our code. Therefore, all the classes in .NET have been divided into namespaces so that classes can be easily referred and managed.

For example, take classes that can be used to paint certain figure on the screen and classes that perform mathematical functions. It would be very inappropriate not to introduce any separating mechanism between these two sets of classes. All the paint classes are somehow related to each other, one class may paint background color, one class may draw a line, square or any other shape, the other draw point and yet another connects these pointes. On the other hand, all the mathematics classes are somehow related; for instance a one class may calculate factorial of the number and other checks whether a number is prime or not and some classes may perform basic and advanced mathematical function. What namespace will do is, group all the paint classes into one namespace and all the mathematic classes into other namespace. Now when a user wants to paint something, he only has to import the paint namespace which will automatically allow him to use all the paint classes. Without namespaces, it would have been extremely difficult to pore through all the classes and import the desired paint or mathematics classes. Thus, namespaces makes code more organized and easier to access.

Exploring Microsoft’s .NET Framework Class Library



Microsoft has provided a detailed reference document on its website. The document contains explanation of every method, property and event of every class in every namespace of the framework class library. This is probably the most detailed and accurate reference document related to namespaces in .NET. Go to this link and you can find all you need to explore the methods, properties and classes in corresponding namespaces in .NET http://msdn.microsoft.com/library/ms229335.aspx

You will reach the following page.

http://imgs.g4estatic.com/c-sharp/namespace/msdn.png

On the above page, you will find a namespace section on the body of the page. Now, scroll down to see the namespace that you want to explore. Just click on the name of the namespace and a new page will appear containing details of all the classes of that namespace.

For Example, click on System.Drawing namespace. A new page will be opened as shown below.

http://imgs.g4estatic.com/c-sharp/namespace/msdn2.png

You can see that the new page contains a class section which contains a list of all the classes that belong to System.Drawing namespace. Brief descriptions of the classes are also given against their names. If you scroll down, you will also see a list of structures, interfaces, delegates and enumerations in the namespace along with their description.

You can see that in the left column, the details of all the classes under the namespace System.Drawing is available. Now suppose if you click on the FontClass on the left, a drop down menu will appear that further contains the FontMethods, FontProperties etc. You can click on them to further view them As shown in the figure below.

http://imgs.g4estatic.com/c-sharp/namespace/msdn3.png

Using Namespaces in Code



Using namespaces to organize code is an extremely simple process. You just have to define a keyword namespace followed by the name of the namespace. Also, you can also specify the hierarchical structure of the namespace using dot operator. See the following code snippet for this purpose.
Code:

namespace level1.level2.level3 {
    class ClassA {
    }
    class ClassB {
    }
}

In the above lines of code, we have specified that the names has three levels of hierarchy. The above lines of code can also be written as
Code:

namespace level1 {
    namespace level2 {
        namespace level3 {
            class ClassA {
            }
            class ClassB {
            }
        }
    }
}

Now, there are two ways to use ClassA and ClassB in your code. The first ways is lengthy and is relatively less readable i.e.
Code:

level1.level2.level3.ClassA objectA;
You can see that this line of code is not easy to handle. If there are three or two levels, we are okay with it but in case a namespace has multiple levels of hierarchy, this method is not feasible. In such cases we use the “Using” directive

Keyword “using”



The using keyword allows you to access a class without specifying fully qualified namespace names as we saw in the last section. For example you can write your code like
Code:

using level1.level2.level3;
class Main {
    static void main() {
        ClassA objectA;
    }
}

You can see that in this case we directly referred to ClassA in our code because we already have imported the namespace through using keyword and we no longer need to use fully qualified namespace name to access this code.

Namespace scope rules



There are certain rules that need to be kept in mind while referring to classes inside the namespaces. Following are some of them.

1. Name scope

The classes defined in outer namespaces are accessible by the code inside the inner namespaces. For example
Code:

namespace level1 {
    namespace level2 {
        class ClassA {
        }
        namespace level3 {
            class ClassB : ClassA {
            }
        }
    }
}

In the above code we defined a class named ClassA inside the namespace level2 and then we have directly accessed it inside the namespace level3. In namespace level three we have declared a ClassB which inherits from ClassA. Remember, colon in C# denotes inheritance relationship.

2. Name hiding

In case if both the outer namespace and inner namespace have classes with same name, in that case class in inner namespace will hide the class name of outer namespace. In order to access the class in outer namespace with the same name as the class in inner namespace, you will have to write fully qualified name. The following code snippet explains this concept.
Code:

namespace level1 {
    namespace level2 {
        class ClassA {
        }
        namespace level3 {
            class ClassA {
            }
            class ClassB {
                ClassA classA;
                // level1.level2.level3.ClassA
                level2.ClassA classA2;
                // level1.level2.ClassA
            }
        }
    }
}

In the above code, we have a class named ClassA in both the namespace level2 and the namespace level3. Now, inside the namespace level3, we declared ClassB. Inside this ClassB we declared two objects classA and classA2. The object classA belongs to class ClassA. Here is the point to be noted, when we wrote ClassA classA, the object classA belongs to the ClassA in the namespace level3, because as we said, the classes with same name in the inner namespace will override or hide the class with same name in the outer namespaces. We want that our object classA2 should be of ClassA type declared in the level2 namespace, for that purpose we will have to write fully qualified name, therefore we wrote level2.ClassA classA2, to remove ambiguities between the classes with similar name.

3. Repeated namespace declaration

For the sake of clarity, you can repeat the namespace whenever you want to define a type inside that name space. For example if you want to declare two classes i.e. ClassA and ClassB in a single namespace. You can do something like
Code:

namespace level1.level2.level3 {
    class ClassA {
    }
}
namespace level1.level2.level3 {
    class ClassB {
    }
}

Both the classes ClassA and ClassB will go into same namespace. An important thing to note here is that you cannot enclose classes with same name in both of the above namespace declaration. For example you cannot write ClassA in both of the above namespace declaration, it would lead to conflict.

You can also break your namespace into two source files. When these file will compile, the code will go into two different .net assemblies. For instance you can do

File1:
Code:

namespace level1.level2.level3 {
    class ClassA {
    }
}

File2:
Code:

namespace level1.level2.level3 {
    class ClassB {
    }
}

4. Nested using directives in namespaces

Apart from inserting ‘using’, you can also insert using directive inside a namespace. It will allow you to access the code from that namespace in the namespace where using directive is located. If you do not use using directive, you will not be able to access the code of the other namespaces inside your name space. Consider the following code snippet.
Code:

namespace level1 {
    class ClassA {
    }
}
namespace level2 {
    using level1 // Imports level1 namespace
    ClassA classA;
    // Accesses the Class in level1 namespace
}
namespace level3 {
    ClassA classA;
    // Cannot Access ClassA because there is no using directive
}

In namespace level1, we declared ClassA and in namespace level2 we imported the namespace level1 via using directive. Therefore, in namespace level2 we are able to access ClassA. On the other hand, we did not import namespace level1 via using directive in namespace level3, therefore, we cannot access ClassA in namespace level3.

5. Importing namespaces and types

Importing a complete namespace can result in type conflict. Therefore, it is always advisable to import only a specific type to avoid ambiguities. This can be done by simple lines of code.
Code:

namespace level1.level2
{
    class ClassA{}
}

Now if you want to access ClassA inside your code, you should try to access the ClassA instead of importing the complete level1.level2 namespace as follows
Code:

using ObjectA = level1.level2.ClassA;

class ClassB
{
    ObjectA a;
}

Here, we have stored ClassA type of namespace level1.leve2 in alias ObjectA via using directive. Now through this alias ObjectA, we can create objects of ClassA inside our code.

One should also try to import the inner most level of a namespace, because it eliminates the possibility of importing types that we do not require. For example if we require the classes in namespace level1.level2 we should not import the whole namespace level1, because that will import other namespaces nested in namespace level1. We require types in namespace level2, therefore we should only import that. Consider the following code
Code:

namespace level1.level2 {
    class ClassA {
    }
    class ClassB {
    }
}
using Level2 = level1.level2;
class ClassC {
    Level2.ClassA objectA;
    Level2.ClassB objectB;
}

Here we have imported the whole inner namespace level2 that is nested in namespace level1. Now we have access to both of its classes ClassA and ClassB. We can assess these classes via the alias Level2 which we created via using directive. Thus we can control the type as well as depth of imported namespaces in our code.

In this article, we have presented a brief overview of namespaces in .NET with special reference to C# languages. We presented several code snippets to explain the namespace concepts. In advanced IDE such as Visual Studio, you will see that a namespace will automatically be created for you when you create a C# project with the name similar to the project name. I would recommend you to create a basic C# console application. Give it some name and when, the project is created you will see that your main class will be inside a namespace having name same as the project you created. In our future tutorials, I will be throwing more light on this topic. Keep visiting this site.


All times are GMT +5.5. The time now is 02:40.