C Sharp Programlama Dili/Nitelikler

Ders 30. Nitelikler


Nitelikler koda bir eleman hakkında ekstra bilgi eklemek için kullanılan ve elemanın bildiriminden hemen önce yazılan özel kodlardır. C#'ta hazır nitelikler olduğu gibi kendi niteliklerimizi de yazabiliriz. Şimdi isterseniz önce hazır niteliklerden başlayalım.

Hazır nitelikler değiştir

Conditional niteliği değiştir

Bu nitelik yalnızca metotlarla kullanılır. Önişlemci komutlarında gördüğümüz sembol programda varsa ilişkili metot çağrılır, nitelikteki sembol programda yoksa metot çağrılmaz. Bu nitelik System.Diagnostics isim alanında bulunur. Örnek program:

 #define TURKCE
 using System;
 using System.Diagnostics;
 class Deneme
 {
    [Conditional("TURKCE")]
    static void Turkce()
    {
       Console.WriteLine("Bu program Türkçedir.");
    }
    [Conditional("ENGLISH")]
    static void English()
    {
       Console.WriteLine("Bu program İngilizcedir.");
    }
    static void Main()
    {
       Turkce();
       English();
    }
 }

Bu program ekrana programın Türkçe olduğunu yazacaktır. Yani program hata vermedi, yalnızca English() metodunun çalıştırılmasını engelledi. Çünkü ilgili sembol programda yoktu.

DllImport niteliği değiştir

Bu nitelik bir metodun .Net ortamında geliştirilmediğini belirtmek için kullanılır. .Net kütüphanesini değil de Windows API'lerini kullanabilmek için bu nitelik gereklidir. Ayrıca ilgili metodun dışarıdan alındığını belirtmek için extern anahtar sözcüğünü kullanırız. Bu nitelik System.Runtime.InteropServices isim alanında bulunur.

DllImport niteliğini bir Windows API fonksiyonu olan MessageBox() üzerinde görebiliriz. Bu fonksiyonu C# programımızda kullanabilmek için DllImport niteliği ile belirtmeli, ayrıca extern anahtar sözcüğü ile de ayrı bir belirtim yapmalıyız. MessageBox Windows programlarında sıkça görebileceğimiz uyarı penceresi anlamına gelir ve üzerinde çeşitli uyarı metinlerinin olduğu bir uyarı penceresi çıkarır. Kullanıcı ekrandaki "Tamam" veya "İptal" gibi butonları tıklayabilir. Şimdi bunları kodsal olarak örnekleyelim.

 using System;
 using System.Runtime.InteropServices;
 class Nitelikler
 {
    [DllImport("User32.dll")]
    public static extern int MessageBox(int aile, string mesaj, string baslik, int tip);
    static void Main()
    {
       MessageBox(0,"Bu bir uyarı mesajıdır","C#",1);
    }
 }

Gördüğünüz gibi kendi metodumuzu oluşturmuş gibi gözüküyoruz. Ancak aslında tek yaptığımız şey User32.dll dosyasından ilgili fonksiyonu alıp programımıza bir metotmuş gibi geçirmek. MessageBox() metodunun son parametresini 0-6 aralığında bir tam sayı yapıp değişik buton kombinasyonları elde edebilirsiniz.

Obsolote niteliği değiştir

Bu nitelikle bir metodun çağrılması durumunda hata ya da uyarı verilmesi sağlanır. Önişlemci komutlarındaki #error ve #warning komutlarına benzer. İki kullanımı vardır:

 [Obsolote("Uyarı mesajı")]

veya

 [Obsolote("Uyarı mesajı", bool hata)]

Birinci örnekte eğer ilgili metot çağrılırsa derleyici uyarı verecektir. Yani program derlenecektir. İkinci örnekte ise eğer hata parametresi true ise program hata verecektir. Yani program derlenmeyecektir. Eğer ikinci örneğin hata parametresi false olursa birincisinden farkı kalmaz. İlk parametreler ise ekrana yazılan hata metnini belirlememizi sağlar. Obsolote niteliği System isim alanında bulunur.

AttributeUsage niteliği değiştir

Bu nitelik ile kendi yazdığımız niteliklerin hangi elemanlarla kullanılabileceğini belirleriz. Parametre olarak AttributeTargets isimli enum nesnesi almaktadır. Bu enumun içerdiği sözcükler şunlardır: All, Assembly, Class, Constructor, Delegate, Enum, Event, Field, Interface, Method, Module, Parameter, Property, ReturnValue, Struct. Bu sözcüklerden tek anlamını çıkaramadığınız tahminimce Module'dür. Module sözcüğü isim alanlarını ifade eder. Örnek

 [AttributeUsage(AttributeTargets.Method)]

Burada niteliğimizin yalnızca metotlara uygulanabileceğini belirttik. Şimdilik buna kafa takmanıza gerek yok. Az sonra kendi niteliklerimizi oluştururken AttributeUsage niteliğini uygulamalı olarak göreceksiniz.

Kendi niteliklerimizi oluşturmak değiştir

Nitelikler aslında System.Attribute sınıfından türetilmiş sınıflardan başka bir şey değildir. O hâlde biz de kendi niteliklerimizi System.Attribute sınıfından türetme yaparak oluşturabiliriz. Örnek:

 using System;
 [AttributeUsage(AttributeTargets.Method)]
 class KendiNiteligimiz:Attribute
 {
    public string Mesaj;
    public KendiNiteligimiz(string mesaj)
    {
       Mesaj=mesaj;
    }
 }
 class AnaProgram
 {
    [KendiNiteligimiz("Mesajımız")]
    static void Metot(){}
    static void Main(){}
 }

Bu programda kendi niteliğimizi oluşturduk ve bu niteliğimizi bir metot üzerinde uyguladık. Niteliklerle ilgili diğer ilginç bir nokta ise niteliği kullanırken parametre verirken nitelikteki özelliklere değer verilebilmesidir. Örneğin:

 [KendiNiteligimiz("Mesajımız",konu="C#",no=5.6)]

Burada niteliğimiz yalnızca bir parametre almasına rağmen diğer parametreler nitelikteki public özelliklere değer atamıştır. Bunu bir örnek üzerinde görelim:

 using System;
 [AttributeUsage(AttributeTargets.Method)]
 class OzelNitelik:Attribute
 {
    public string Mesaj;
    public int No;
    public string Konu;
    public OzelNitelik(string mesaj)
    {
       Mesaj=mesaj;
    }
 }
 class Deneme
 {
    [OzelNitelik("Mesajımız",No=5,Konu="C#")]
    static void Metot(){}
    static void Main(){}
 }

İlk parametre normal parametre olmalıdır. Diğerlerinden bazıları ya da tamamı olmayabilir. İlk parametre dışındakilerin kendi arasındaki sırası önemli değildir.

Bir elemana ilişkin nitelikleri yansıma yoluyla elde etmek için Attribute sınıfının static GetCustomAttribute() metodu kullanılabilir. Örnek:

 using System;
 class Yansima
 {
    static void Main()
    {
       Type t=typeof(Array);
       Attribute[] dizi=Attribute.GetCustomAttributes(t);
       foreach(Attribute a in dizi)
          Console.WriteLine(a);
    }
 }

Benim bilgisayarımda program şu çıktıyı verdi:

System.SerializableAttribute
System.Runtime.InteropServices.ComVisibleAttribute

Yani System.Array sınıfı bu iki niteliği kullanıyormuş. Yansıma yoluyla bir türün veya üye elemanın niteliklerini elde ettiğimizde aslında ilgili tür veya üye elemanın başındaki nitelikteki değerler kullanılarak ilgili nitelik sınıfı nesnesi oluşturulur. Geriye bu nesne döndürülür. Daha sonra bu nesne üzerinden niteliğin farklı kısımlarına ulaşabiliriz.

Bu kitabın diğer sayfaları
  • Sınıflar
  • Operatör aşırı yükleme
  • İndeksleyiciler
  • Yapılar
  • Enum sabitleri
  • İsim alanları
  • System isim alanı
  • Temel I/O işlemleri
  • Temel string işlemleri
  • Kalıtım
  • Arayüzler
  • Partial (kısmi) tipler
  • İstisnai durum yakalama mekanizması
  • Temsilciler
  • Olaylar
  • Önişlemci komutları
  • Göstericiler
  • Assembly kavramı
  • Yansıma
  • Nitelikler
  • Örnekler
  • Şablon tipler
  • Koleksiyonlar
  • yield
  • Veri tabanı işlemleri
  • XML işlemleri
  • Form tabanlı uygulamalar
  • Visual Studio.NET
  • Çok kanallı uygulamalar
  • ASP.NET