Słowo kluczowe namespace deklaruje nam obszar nazw, który wykorzystujemy. Możemy się odwołać do elementów z innego obszaru nazw, musimy wtedy napisać przed elementem do którego chcemy się odwołać pełną nazwę obszaru. Zobaczmy przykład:

Napiszmy klasę Rectangle w obszarze nazw nazwanym one. W obszarze nazw two napiszmy kod programu, który wykorzysta naszą klasę. Całość umieśćmy w jednym pliku:

namespace one{
    class Rectangle {       
    }
}
namespace two {
    class Program {
        static void Main() {
            Rectangle _rectangle = new Rectangle();
        }
    }
   
}

Kompilator zgłosi następujący błąd:
namespace1

Rys. Błąd zgłoszony przez kompilator

Jak widzimy kompilator zgłasza błąd mimo, że klasa Rectangle znajduje się w jednym pliku co kod programu. Dzieje się tak, ponieważ wykorzystujemy różne obszary nazw. Zobaczmy jak odwołać się do klasy Rectangle, która znajduje się w innym obszarze nazw:

namespace two {
    class Program {
        static void Main() {
              one.Rectangle _rectangle = new one.Rectangle();              
           }
    }   
}

Gdy chcemy się odwołać do innej przestrzeni nazw wpisujemy jej nazwę, potem kropkę, a po niej interesujący nas element. Kompilator nie zgłosi błędu i kod się skompiluje.

Taki zapis jednak jest problematyczny, aby pozbyć się pisania dodatkowego kodu w postaci nazwy przestrzeni nazw, możemy skorzystać ze znanego nam już słowa kluczowego using:

using one;
namespace two {
    class Program {
        static void Main() {
              Rectangle _rectangle = new Rectangle();              
           }
    }   
}

Dzięki użytemu słowu kluczowemu using, kompilator wie do jakiej przestrzeni nazw ma się odwołać i nie zgłosi błędu. Kod klasy Rectangle nie musi być w tym samym pliku .

namespace2

Rys. Kod z przykładu w dwóch różnych plikach.

Należy pamiętać, że istnieje możliwość występowania w różnych przestrzeniach nazw klas o takiej samej nazwie. Aby zilustrować problem dodajmy nową przestrzeń nazw three w której umieścimy klasę o nazwie Rectangle:

using one;
using three;
namespace two {
    class Program {
        static void Main() {
              Rectangle _rectangle = new Rectangle();              
           }
        public void MethodOne { }
    }   
}
namespace one {
    class Rectangle {}
}
namespace three {
    class Rectangle {}
}

namespace3

Rys. Błąd zgłoszony przez kompilator

Kompilator zgłasza nam błąd, ponieważ istnieje konflikt nazw. Kompilator nie wie z której klasy ma stworzyć obiekt czy Rectangle z przestrzeni nazw one czy może Rectangle z przestrzeni nazw three. W takim wypadku zmuszeni jesteśmy do pisania pełnych nazw przestrzeni nazw:

using one;
using three;
namespace two {
    class Program {
        static void Main() {
              one.Rectangle _rectangle = new one.Rectangle();              
           }
        public void MethodOne { }
    }   
}
namespace one {
    class Rectangle {}
}
namespace three {
    class Rectangle {}
}

Kompilator nie zgłosi nam błędu bo już wie jakiej klasy Rectangle ma stworzyć obiekt. Gdy w tych przestrzeniach nazw będą dodatkowo inne klasy o różnych nazwach, możemy z nich bez problemu korzystać:

using one;
using three;
namespace two {
    class Program {
        static void Main() {
              one.Rectangle _rectangle = new one.Rectangle();
              classA obiectA = new classA();
              classB obiectB = new classB();
           }
        public void MethodOne { }
    }   
}
namespace one {
    class Rectangle {}
    class classA { }
}
namespace three {
    class Rectangle {}
    class classB { }
}

Kompilator nie zgłosi żadnego błędu i kod się skompiluje. Wie on jakie obiekty, jakich klas z różnych przestrzeni nazw ma stworzyć.

Podsumowanie:
Słowo kluczowe namespace określa nam przestrzeń nazw w jakiej operujemy. Możemy tworzyć w projekcie wiele przestrzeni nazw aby logicznie oddzielić moduły swojej aplikacji.

Wykorzystując słowo kluczowe using, możemy sobie skrócić zapis. Musimy jednak uważać aby nie zmniejszyć czytelności naszego kodu.

Słowa kluczowego using, możemy użyć do szybkiego wykorzystania obiektu jednak, aby to było możliwe, klasa opisująca obiekt, musi implementować interfejs IDisposable.