|
C#'ta Nitelikler (Attributes) |
|
Gönderiliyor lütfen bekleyin... |
|
|
Bu makalede C# dilinde
Niteliklerin nasıl kullanıldıklarını birlikte örneklerimizle öğreneceğiz.
.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 .NETteki 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
//
} |
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 20nin ü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;
using System.Diagnostics;
namespace Conditional_Attribute
{
public class TestSinifi
{
public void Metot_A()
{
Console.WriteLine("Metot_Adan merhaba dünya !");
}
[Conditional("DEBUG")]
public void Metot_B()
{
Console.WriteLine("Metot_Bden merhaba dünya !");
}
public void Metot_C()
{
Console.WriteLine("Metot_Cden 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. TestSinifinda üç adet metot tanımı yapıyoruz.
Bunlardan Metot_Bye [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_Adan merhaba
dünya !
Metot_Cden 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_Adan merhaba
dünya !
Metot_Bden merhaba dünya !
Metot_Cden 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", "[email protected]",
"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();
}
}
}
|
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.
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");
}
}
}
|
Yukarıdaki
kodu derlediğimizde derleyici aşağıdaki gibi bir uyarı verecektir:
Bu makalede
C# niteliklerinin temellerini ve .NET sınıf kütüphanesinde bulunan bir kaç
niteliği örneklerle inceledik. İlerleyen makalelerde kendi niteliklerimizi
yazmayı inceleceğiz.
Makaledeki
örnek kodları indirmek için
tıklayınız
Makale:
C#'ta Nitelikler (Attributes) C#, Visual C# ve .NET Ahmet Faruk Nacaroğlu
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|