C# namespaces (İsim Alanları)

Merhaba arkadaşlar,

Bu yazımda C# programlama dilinde programlarımızı yönetmek ve yazdığımız kodları mantıksal olarak organize etmek için C# programlama dilinde kullanılan İsim alanları ve System İsim Alanını ele alacağız. Bir önceki yazımda C# programlama dilinde Numaralandırma (Enumearation) hakkında bahsetmiştik. C# Enumeration (Numalandırmalar) yazısına buradan ulaşabilirsiniz.

Bu yazıda bahsedilecek konular

  • İsim Alanı Nedir?
  • İsim Alanı Bildirimi
  • using anahtar sözcüğü
  • İç içe (nested) geçmiş isim alanları
  • External Alias (Harici Takma İsimler)

İsim Alanı Nedir?

İsim alanları, yazdığımız programlamalarda mantıksal organizasyonu sağlar. Kodların organizasyonu kavramı yalnızca yazılım teknolojisinin hızlıca büyümesi ile ilgilidir. Gün geçtikçe dünyanın yazılıma olan ihtiyacı artmaktadır. Hal böyle olunca büyüyen projeler ve bu projelerde görev alan programcıları düşünürsek bunu yönetebilmek için organizasyonun iyi olması gerekiyor. Organizasyondan kasıt her bir programcının yazdığı kodların ortak bir platformda toplandığı zaman derleme aşamasında hataya sebep açılmamasıdır. Bu hataların en genel sebebi yazılan fonksiyon/metotların isim karışıklığından meydana gelen hataların ortaya çıkmasıdır.

İşte bu tür karmaşıklığın önüne geçmek için hemen hemen bütün modern programlama dilinde programın mantıksal bir yapı içinde olması için çeşitli yollar uygulanıyor. Örneğin C++ ve C# dilinde isim alanları (namespace) ki bizim üstünde duracağımız konu 🙂 Java dilinde package mekanizmasının olması gibi.

C# programlama dilinde isim alanları sayesinde isim benzerlikleri bir sorun olmaktan çıkıyor. Örneğin System isim alanında bulunan Array sınıfının yanında kendi yazacağımız Array sınıfı da tasarlayabiliriz. İşte isim alanları yalnızca mantıksal organizasyonu sağlamaktadır. C++ dilindeki include anahtar sözcüğü ile karıştırılmamalıdır. include anahtar sözcüğü ile dosyalar birbirine fiziksel olarak bağlanırken isim alanları ile sadece mantıksal bir işlem yapılır. Yani isim alanları sadece derleme aşaması ile ilgilidir.

Eğer isim alanları olmasaydı bütün değişkenler ve metotlar global düzeyde tanımlanıyor olacaktı ve buda müthiş bir karışıklığa sebep olurdu.

Aslında isim alanlarına aşina gibiyiz çünkü C# programlama dilini öğrenmeye çalıştığımızda isim alanları hep vardı 🙂

Yukarıdaki kullanım ile derleyicimize biz System isim alanını kullanmak istediğimizi bildiriyoruz. Tabi yukarıdaki bildirimi yapmadan da kullanabilirdik. Aşağıdaki kullanım da geçerlidir.

Yaptığımız yukarıdaki bildirimde System isim alanını kullanarak Console sınıfına erişebildik. Çünkü mantıksal olarak Console sınıfı System isim alanında bulunuyor. Eğer System isim alanı ile kullanmamış olsaydık derleyici bize Console diye bir şeye anlam yükleyemiyorum 🙂 hatası verecekti.

Temel veri türlerini System isim alanı eklemeden de kullanabiliriz. Bunun sebebi C# derleyicisi temel veri türlerini otomatik olarak System isim alanından türetmesidir.

Bir başka bilmemiz gereken bilgi ise Sınıflarımızı ve diğer tür bildirimlerinizi bir isim alanında yapmazsak derleyici kodlarımız için otomatik bir isim alanı belirleyecektir.

Örneğin aşağıda isim alanı dışında tanımladığımız sınıf isim alanında bildirilmemesine rağmen Main() metodu içinde tanımlanabiliyor. Bunun sebebi global düzeyde tanımlanan tipler için otomatik bir isim alanı tanımlanmasıdır. O zaman aşağıdaki durum geçerli olur.

İsim Alanı Bildirimi

İsim alanları namespace anahtar sözcüğü kullanılarak bildirilir. Bu anahtar sözcükten sonra isim alanın ismi belirtilir.

Bu bildirimden sonra İsim Alanında bir sınıf oluşturup bu sınıfı nasıl bildirdiğimize bakalım

Sınıfımızdan bir nesne oluştrurken CSharp isim alanı ile bildiriyoruz. Bunun sebebi ise artık MyNameSpace sınıfı global düzeyde değil ve o yüzden derleyici MyNameSpace sınıfı ile ne yapacağını bilmediği için ilgili sınıfın isim alanı ile nesne oluşturuyoruz.

İsim alanları bir diğer özelliği ise fiziksel olarak başka yerde tanımlanarak farklı yerde bulunan türlerin aynı mantıksal düzeyde olmasını sağlar. Ne demek istediğimizi örnekle açıklayalım. Bunun için ihtiyacımız olan iki farklı sınıf ve bu sınıflar fiziksel olarak iki farklı dosyalarda olacak.

Programı derleyip çalıştırdığımızda hata almayız. İşte aynı isimli birden fazla isim alanı farklı farklı dosyalarda oluşturabilmemiz isim alanları sayesinde bu da mantıksal bir gruplama yaptığını gösteriyor.

İsim alanları yalnızca tür bildirimleri içermelidir. Herhangi bir değişen tanımlaması veya değişken yer alamaz. Aynı şekilde metot bildirimleri için de bu durum geçerlidir. Buna göre aşağıdaki bildirim geçersizdir;

Not: isim alanlarında yalnızca sınıf (class), temsilci (delegate) numaralandırma (enum), arayüz (interface), ya da yapı (struct) bildirimleri yapılabilir.

using Anahtar Sözcüğü

using anahtar sözcüğü ile kodunuza isim alanlarını eklemeden sınıf kütüphanesini kullanabiliriz. Örneğin ArrayList sınıfını ele alırsak bir nesne oluşturmak için aşağıdaki bildirimi yapmamız gerekir.

Yukarıdaki bildirimi using anahtar sözcüğü ile yapabiliriz. using anahtar sözcüğü ile System isim alanı altında bulunan Collection isim alanını koda dahil ederek derleyiciye bu isim alanında bulunan türleri programa dahil et diye belirtiriz. O zaman aşağıdaki bildirim geçerlidir

using deyimleri herhangi bir nesne tanımlaması veya isim tanımlaması bildirimi yapılmadan önce kaynak koda eklenmelidir. Aşağıdaki kullanım hatalıdır.

using anahtar sözcüğünün diğer bir kullanımı ise belirlenen bir bloğun sonunda nesnelerin Dispose() metodunu çağırmasıdır. using anahtar sözcüğünün bu şekilde kullanılabilmesi için IDisposible arayüzü ilgili sınıfa uygulanması gerekiyor. Bu yüzden temel düzeyde bu kullanımı göstermek için bu arayüz kullanılacaktır.

Bir using parantezi içinde sadece bir türden bir nesne tanımlaması yapılabilir!

using ile Takma İsim (Alias) Verme

Bazen aynı isimli türlerin aynı isim alanı içinde bulunması belirsizliğe yol açabilir.

Yukarıdaki programı yazıp derlemeye çalıştığında ‘Printer’ is an ambiguous reference between ‘Print2D.Printer’ and ‘Print3D.Printer’ hatası alırsınız. Yani Printer belirsiz bir referanstır benim kafam karıştı demek istiyor 🙂 işte bu tür yaşanan durumları çözmek adına takma isim alanlarına başvururuz. using anahtar sözcüğü aşağıdaki gibi kullanılır

Takma ad kullanımı .NET Sınıf kütüphanesi içinde kullanılabilir! Aşağıdaki kullanım geçerlidir.

İç İçe geçmiş İsim alanları

Büyük çaplı yazılım projelerinde (.NET Sınıf Kütüphanesi gibi) isim alanlarında arklı isim alanları bildirilebilir. Örneğin System isim alanı altında bulunan Collection isim alanı gibi. İç içe belirlenmiş isim alanları “.” operatörü ile using anahtar sözcüğü kullanılarak kaynak koda eklenir.

Yukarıdaki örneği using anahtar sözcüğü ile de yapabiliriz. Buna göre aşağıdaki bildirim geçerlidir.

External Alias (Harici Takma İsimler)

C# 2.0’dan itibaren C# dilinde dll kütüphanelerine (Assembly) harici takma isimler verebiliyoruz. Daha önce takma isimle aynı isimli türlerin aynı isim alanı içinde bulunması ile oluşan sorunu çözebiliyoruz. Şimdi ise aynı sorunu extern alias yöntemi ile çözmeye çalışacağız.

Bunun için daha önce kullandığımız Printer2D ve Printer3D sınıflarını kendi başlarına yeni bir Class Library oluşturarak derleyeceğiz ve oluşan 2 dll (assembly) ana programımızda ekleyerek alias yardımı ile oluşan karışıklığın önüne geçmek temel amacımız.

İlgili Dll’leri ana programımıza ekledikten sonra her bir dll takma isim veriyoruz. Ben derleyici olarak Visual Studio Code kullandığım için aşağıdaki yöntem geçerlidir.

Dll’leri ana programa ekledikten sonra .csproj uzantılı dosyanıza ilgili dll’lerin referencepath’leri eklenmiş olacak. ProjectReference aşağıdaki gibi Aliases etiketi ile verebilirsiniz

Printer2D dll’ne P2D ve Printer3D dll’ne P3D takma ismini verdikten sonra ana programımızda aşağıdaki gibi kullanabiliriz.

Çok Önemli: extern alias anahtar sözcüğü bütün using anahtar sözcüklerinden önce yazılmalıdır!

Takma isimleri verdikten sonra aynı isme ait özelliklerine erişebiliriz. Ancak bunu klasik yollar ile yapamamaktayız. Bunun için :: Operatörünü kullanmalıyız

:: Operatörü

Harici takma isim verilmiş dll kütüphanelerindeki tip ve isim alanlarına erişmek için C# 2.0 ile birlikte yeni bir operatör eklendi. :: operatörü sadece harici isim verilmiş kütüphaneler için kullanılır.

Şimdi ise extern alias tanımı yapıldıktan sonra Print metoduna aşağıdaki gibi erişebiliriz.

ya da using anahtar sözcüğü ile aşağıdaki gibi kullanabiliriz

global Harici Takma İsmi

.Net içerisinden referans verilmiş herhangi bir kütüphaneye siz farkında olmadan bile otomatik olarak bir takma isim verilir. (Tabi isterseniz değiştirebilirsiniz). Bu takma ismin adı global‘dır. C# programınızı derledğinizde System.dll gibi birçok temel kütüphane otomatik olarak referans verildiğinden bu kütüphanelere aynı zamanda otomatik olarak global isminde harici bir takma isim verilir.

global isimli harici takma ismine kod üzerinden aşağıdaki gibi erişebiliriz.

global, partial gibi C# diline sonradan eklenen kelimeler anahtar sözcük olmasına rağmen geriye dönük uyumluluktan ötürü bu anahtar sözcükler herhangi bir değişken ismi olarak kullanılabilmektedir.

Bu yazımda C# programlama dilinde İsim Alanları (namespace) hakkında elde ettiğim bilgileri paylaştım. İsim alanları sayesinde büyüyen programlarımızı mantıksal olarak nasıl organize edebileceğimizi temel anlamda öğrenmiş olduk. Umarım faydalı olmuştur.

Bir sonraki yazımda görüşmek üzere 🙂

Leave a Comment