.NET Uygulamalarında temel olarak; program kodu, veri ve metadata olunur. Metadata veri hakkında veri olarak tanımlanır ve programın binary dosyalarının (exe veya dll gibi)içine gömülür. Program kodu, assembly ve veri tipleri, metotlar vs.. hakkında metadataları .NET platformda bulmak mümkündür.
Nitelikler(Attributes) ile programlarımıza ve onun elemanlarına derleyici direktifleri(compiler instructions) ve diğer metadata bilgilerini ekleyebiliriz. Nitelikleri ILDasm ile okuyabilir/görebiliriz. Bu sayede C# dilinin kendisini de genişletebiliriz. Bunun nasıl yapıldığı makalenin ilerleyen kısımlarında örnekler ile inceleyeceğiz.Nitelikler aslında C# veya .NET'teki diğer nesneler gibi birer nesnedir. İki tür nitelik bulunmaktadır; birincisi CLR içinde gelen niteliklerdir. Diğeri ise programcının kendisinin oluşturduğu niteliklerdir. Niteliklerin program içinde değişik elemanlara ait olabileceklerini söylemiştik.
C# dilinde;
- Sınıflara,
- Sınıf
üyelerine( alanlar, metotlar, özellikler, indeksleyiciler,
yapılandırıcılar, yıkıcılar),
- Yapılara,
- Arayüzlere,
- Arayüz
elemanlarına( metotlar, özellikler, olaylar, indeksleyiciler),
- Enumarasyonlara
ve üyelerine
- Delegelere
En basit nitelik kullanımı örneği olarak C#'da konsol uygulaması projesi verebiliriz.
///
<summary>
/// The main entry point for the application. /// </summary> [STAThread] static void Main(string[] args) { // // TODO: Add code to start application here // } |
Nitelikler parametrik olarak tanımlanmış olabilir. Niteliklere parametre aktarmak parametreleri nitelik isminden sonra parantez içinde yazarız:
[NitelikIsmi(parametre)]
Nitelik isimlerinde ilginç bir hususu da burda belirtmek gerekiyor. Normalde nitelik isimlerinde "Attribute" sonek (suffix) bulunur. Örnek [ObsoleteAttribute] niteliğini verebiliriz. Fakat "Atrribute" sonekini belirtmeden nitelikleri kullanmamız mümküdür( [Obsolete] gibi ).
Niteliklerin tanımını, hangi amaçlarla kullanıldıklarını öğrendikten sonra .NET içinde varsayılan olarak gelen niteliklerin çok kullanılanlarını incelemeye geçebiliriz. Ancak bu noktada şunu vurgulamak gerekir ki, nitelikler sadece C# diline has bir özellik değildir. Diğer .NET uyumlu diller de nitelikler tanımlanabilir ve kullanılabilir.
.NET Framework Nitelikleri Örnekleri
.NET sınıf
kütüphanesinde yüzlerce nitelik sınıfları bulunmaktadır. Bunların tamamını burada
incelememiz mümkün değildir. Hepsi kullanıldıkları yerlerde anlamlanıyorlar.
Mesala COM interop ile ilgili işlemleri yaparken kullanılan sınıflarla birlikte
20'nin üzerinde nitelik tanımlanmıştır. COM interop konularını anlatan makale,
kitap veya MSDN dökümantasyonlarında bunları nerde nasıl kullanılacakları tek
tek detaylı biçimde açıklanmıştır.
1.
System.Diagnostics.ConditionalAttribute
Sadece
metotlara uygulanan ConditionalAttribute ya da kısaca Conditional niteliği;
program kodu içindeki belirli bir metodu derlerken koda dahil edip
etmeyeceğimizi bildirmek için kullanılır. Bunun için derleyiciye derleme
sırasında geçilen define
parametresinden faydalanırız. İsterseniz Conditional niteliğinin nasıl
kullanıldığına dair bir örnek yapalım.
using
System;
namespace Conditional_Attributeusing System.Diagnostics; { public class TestSinifi { public void Metot_A() { Console.WriteLine("Metot_A'dan merhaba dünya !"); } [Conditional("DEBUG")] public void Metot_B() { Console.WriteLine("Metot_B'den merhaba dünya !"); } public void Metot_C() { Console.WriteLine("Metot_C'den merhaba dünya !"); } } class ConditionalAttributeProgram { public static void Main() { TestSinifi myTestSinifi = new TestSinifi(); myTestSinifi.Metot_A(); myTestSinifi.Metot_B(); myTestSinifi.Metot_C(); } } } |
Önce programımızı aşağıdaki gibi derleyelim:
csc ConditionalAttributeProgram
Derlenen kodu çalıştırdığımızda şu şekilde bir sonuç elde ederiz:
Metot_A'dan merhaba dünya !
Metot_C'den merhaba dünya !
Ama bir saniye, biz Main() metodu içinde Metot_A(), Metot_B() ve Metot_C()'yi çağırdık. Fakat Metot_B() çağrımız dikkate alınmadı. Sebebi ise Metot_B() 'ye eklediğimiz [Conditional("DEBUG")] niteliğini eklememiz ve derlememe işlemini Debug mod yerine Release modda yaptık. Eğer kodumuzu
csc /d:DEBUG ConditionalAttributeProgram
veya
csc /define:DEBUG ConditionalAttributeProgram
şeklinde derleyip derleyip çalıştırırsak şöyle bir çıktı elde ederiz:
Metot_A'dan merhaba dünya !
Metot_B'den merhaba dünya !
Metot_C'den merhaba dünya !
Sonuç olarak derleme işleminde "DEBUG" sembolu eklemezsek, kod içindeki [Conditional("DEBUG")] niteliği ile işaretlenmiş metotları derleyeyici dikkate almıyor.
Sizlerde isterseniz kendi özel sembollerinizi kullanarak derleme işlemi üzerinde kontrol sahibi olabilirsiniz. Mesela TEST sembolü ile test kodunu yazdığınız metot(ları) deneyebilirsiniz.
2.
System.SerializableAttribute
Serializable
niteliği sınıflara uygulanır ve sınıfın verilerinin sabit disk veya başka bir
depolama birimine serileştirilebileceğini belirtir. Bu sayede sınıf içindeki
tüm alanlarını serileşebilir olarak işaretlenir. Eğer bir takım sınıf
verilerini serileştirmek istemiyorsak bunları NonSerialized niteliği ile
işaretleyebiliriz. Serializable niteliğinin nasıl kullanabileceğimize dair tam örnek program kodumuz ise:
using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; namespace SerializationAttributeProgram { [Serializable()] public class Kullanici { public string ismi; public string email; public string telefon; //Serileştirmek istemediğimiz sınıf alan [NonSerialized()] public string parola; public Kullanici(string Ismi, string Email, string Telefon, string Parola) { this.ismi = Ismi; this.email = Email; this.telefon = Telefon; this.parola = Parola; } public Kullanici() { } public void Serilestir() { Stream streamYaz = File.Create("KullaniciKaydi.bin"); BinaryFormatter binaryYaz = new BinaryFormatter(); binaryYaz.Serialize( streamYaz, this ); streamYaz.Close(); } public static Kullanici DeSerilestir() { Stream streamOku = File.OpenRead("KullaniciKaydi.bin"); BinaryFormatter binaryOku = new BinaryFormatter(); Kullanici yeniKullanici = new Kullanici(); yeniKullanici = (Kullanici)binaryOku.Deserialize(streamOku); streamOku.Close(); return yeniKullanici; } public override string ToString() { string strReturn = " Ismi: " + this.ismi + "\n"; strReturn += " Email: " + this.email + "\n"; strReturn += " Telefon: " + this.telefon + "\n"; strReturn += " Parola: " + this.parola + "\n"; return strReturn; } } public class SerializationAttributeProgram { public static void Main() { Kullanici kullanicim = new Kullanici("Ahmet Faruk", "nacaroglu@nacaroglu.net", "0555-6663399", "parolam"); Console.WriteLine(" Serileştirmeden önce kullanıcım: "); Console.WriteLine( kullanicim.ToString() ); Console.WriteLine(" ----------------------------------------------- "); kullanicim.Serilestir(); Kullanici yeniKullanici = Kullanici.DeSerilestir(); Console.WriteLine(" DeSerileştirmeden sonra kullanıcım: "); Console.WriteLine( yeniKullanici.ToString() ); Console.ReadLine(); } } } |
SerializationAttributeProgram sınıfı ise sadece Main() metodu içermektedir ve sadece Kullanici sınıfını test etmek içindir. Kodu derleyip çalıştırdığımızda şu sonucu alırız:
Dikkat ederseniz Kullanici sınıfı [Serializable()] ile işaretlenmiş. Fakat, ToString() metodunda parola verisi de sonuç olarak geri döndürüldüğü halde, DeSerileşmiş kullanıcı kaydında parola boş olarak görünüyor? Çünkü parola alanını biz [NonSerialized()] niteliği ile işaretledik!
3.
System.ObsoleteAttribute
Bu
makalede son olarak Obsolete niteliğini inceleyeceğiz. Program kaynak kodunda
varolan bir kod elemanın artık kullanılmayacağı durumlarda onu koddan silmek
yerine [Obsolete] niteliği ile
işaretleyebiliriz. Bu nitelik assembly dışında tüm kod elemanları için
kullanılabilir. Obsolete niteliğinin Message(string) ve IsError(bool) olmak
üzere iki tane özelliği parametre ile niteliğe geçirilebilir. Varsayılan olarak
IsError false değeri alır ve uyarı(Warning). Eğer IsError özelliğini true
yaparsak derleme zamanında hata olarak karşımıza çıkar. Message özelliği ise
niteliğin tanımlanma sebebini içerebilir ve bu hata/uyarı mesajında
görüntülenir.
using System; namespace ObsoleteAttributeProgram { class ObsoleteAttributeProgram { [STAThread] static void Main(string[] args) { Console.WriteLine( ObsoleteAttributeProgram.MerhabaDunya() ); Console.ReadLine(); } [Obsolete("MerhabaDunya metodu artık kullanılmıyor", false )] public static string MerhabaDunya() { return ("HelloWorld"); } } } |
Bu makalede C# niteliklerinin temellerini ve .NET sınıf kütüphanesinde bulunan bir kaç niteliği örneklerle inceledik.
Hiç yorum yok:
Yorum Gönder