.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
uygulanmak üzere nitelikler tanımlayabiliriz. Tanımlanan nitelikleri
kullanırken onları köşeli parantezler ,[NitelikIsmi] gibi, içinde belirtiriz.
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
//
}
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
}
Yukarıdaki kod içerisindeki [STAThread] niteliği Main fonksiyonuna
yugulanmak üzere tanımlanmıştır. Bu sayede Main() metodumuz herhangi bir COM
tabanlı kod çalıştırılmadan önce COM Single Thread Apartment’ına (STA) girmesi
gerektiği derleyiciye bildiriliyor.
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 using System;
using System.Diagnostics;
using System.Diagnostics;
namespace
Conditional_Attribute
{
public class TestSinifi
{
public void Metot_A()
{
Console.WriteLine("Metot_A’dan merhaba dünya !");
}
{
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();
}
}
}
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();
}
}
}
Yukarıdaki programınız konsol uygulaması olup iki sınıf içermektedir:
TestSinifi ve ConditionalAttributeProgram. TestSinifi’nda üç adet metot tanımı
yapıyoruz. Bunlardan Metot_B’ye [Conditional("DEBUG")] niteliğini ekledik. Diğer sınıfta ise sadece Main() metodu bulunmaktadır.
Ö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 !
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 !
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:
parametresinden faydalanırız. İsterseniz
Conditional niteliğinin nasıl kullanıldığına dair bir örnek yapalım.
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace SerializationAttributeProgram
{
[Serializable()]
public class Kullanici
{
public string ismi;
public string email;
public string telefon;
{
[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;
[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;
}
{
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();
}
{
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");
{
Stream streamOku = File.OpenRead("KullaniciKaydi.bin");
BinaryFormatter binaryOku =
new BinaryFormatter();
Kullanici yeniKullanici =
new Kullanici();
yeniKullanici = (Kullanici)binaryOku.Deserialize(streamOku);
streamOku.Close();
return yeniKullanici;
}
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";
{
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");
{
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();
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();
}
}
}
Console.WriteLine(" DeSerileştirmeden sonra kullanıcım: ");
Console.WriteLine( yeniKullanici.ToString() );
Console.ReadLine();
}
}
}
Yukarıdaki kodda iki sınıfımız bulunmaktadır. Birincisi Kullanici ve ikincisi SerializationAttributeProgram
sınıflarıdır. Kullanici sınıfında iki tane yapılandırıcı (biri varsayılan diğeri parametrik), Serilestir(), DeSerilestir() ve ToString() metotları bulunmaktadır.
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();
}
{
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");
}
}
}
public static string MerhabaDunya()
{
return ("HelloWorld");
}
}
}
Hiç yorum yok:
Yorum Gönder