C#

Delegete Nedir, Nasıl Kullanılır

C# programlama dilinde ileri seviye kavramlardan biri olan Delegates(temsilciler)’i inceleyecegiz. Her seviyeden C# programcısının bilmesi gereken unsurlardandır. Uygulamalarımızı temsilciler olmadan da geliştirebiliriz. Ancak bu durumda, yapamayacaklarımız yapacaklarımızdan daha çok olacaktır.

Temsilci (delegate), program içerisinde bir veya daha fazla metodu gösteren(işaret eden), referans türünden bir nesnedir. Programlarımızda temsilciler kullanmak istediğimizde, öncelikle bu temsilcinin tanımını yapmalıyız. Temsilci tanımları, arayüzlerdeki metod tanımlamaları gibidir. Tek fark “delegate” anahtar sözcüğünü kullanırız. Temsilci tanımları tasarım zamanında yapılır. Bir temsilciyi, bir metodu işaret etmesi için kullanmak istediğimizde ise, çalışma zamanında onu new yapılandırıcısı ile oluşturur ve işaret etmesini istediğimiz metodu ona parametre olarak veririz

Bir temsilcinin tanımlanması, onu kullanmak için yeterli değildir. Her şeyden önce temsilciyi kullanmak için bir amacımız olmalıdır. Bir temsilciyi çalışma zamanında oluşturabilir ve kullanabiliriz. Bir temsilci sadece bir tek metod için tanımlanmış olabilir veya birden fazla metod içinde tanımlanmış olabilir. Diğer yandan, tek bir temsilcide birden fazla temsilciyi toplayarak bu temsilcilerin işaret ettiği, tüm metodları tek bir seferde çalıştırma lüksünede sahibizdir. Ancak temsilciler gerçek anlamda iki amaçla kullanılırlar.

1.Events(olaylar)

2. Metodun çalışma zamanında, hangi metodların çalıştırılacağına karar vermesi gerektiği durumlarda delegate kullanırız.

Delegate kullanmadan da programlarımızı yapabiliriz ama bize sağladığı üstün programlama tekniği, kullanım kolaylığı ve artan verimliliği de göz ardı etmiş oluruz.

DELETE EVENT KULLANIMI

Delete tanımlası şu şekilde olur:

public delegate void My1DelegeHandler(int a,int b);
//Geri dönüş tipi olmayan ve int tipinden iki adet parametre alan metodlar için kullanılır.
public delegate int My2DelegeHandler(int a,int b);
//Geri dönüş tipi int olan ve int tipinden iki adet parametre alan metodlar için kullanılır.
public delegate string My3DelegeHandler();
//Geri dönüş tipi string olan ve parametre almayan metodlar için kullanılır.

Şimdi delegeyi kullanmayı görelim.

public delegate void DenemeHandler();
public void deneme()
{
MessageBox.Show("deneme metodu");
}
private void Form1_Load(object sender, EventArgs e)
{
deneme();
}

Bu deneme metodunu DenemeHandler delegate i tarafından nasıl çalıştırılabilir Onu görelim.

private void Form1_Load(object sender, EventArgs e)
{
DenemeHandler delege = new DenemeHandler(x);
//Delegeden nesne yarattık.
}

Formun Load kısmına bu kodu yazıp çalıştırırsak mesaj kutusunda “deneme metodu” yazacaktır ya da şöyle bir şey deneyelim.

private void Form1_Load(object sender, EventArgs e)
{
DenemeHandler delege = new DenemeHandler (deneme);
delege.Invoke();
//delegenin işaret ettiği metod, delegenin Invoke metodu aracılığıyla da çalıştırılabilir.
}

Şimdi ise delege kullanımına bir örnek daha gösterelim.

public delegate int HesaplaHandler(int a,int b);
public int Toplama(int a1, int a2)
{
return a1 + a2;
}
public int Carpma(int a1, int a2){
return a1 * a2;
}


Yukarıda int tipinde döndüren ve iki parametre alan ve bu parametreler de int tipinde olan metod yazdık


private void Form1_Load(object sender, EventArgs e)
{
HesaplaHandler delege = new HesaplaHandler (Toplama);
MessageBox.Show(delege(2, 3).ToString());
//veya
MessageBox.Show(delege.Invoke(2, 3).ToString());
}

Ve yazdığım bu metodları “delege” isminde delegate nesnesine adreslettirdim.delege(2,3) veya delege.Invoke(2,3) diyerek, programı derleyip çalıştırdığımda ekranda 5 yazısını göreceğiz.

NOT:"delege" isimli delegate nesnesi hem Toplama hem de Carpma metodlarını adresleyebilir. Ben yukarıda sadece Toplama metodunu adreslettim. Şimdi gelin Carpma metodunuda “delege” isimli delegate’mize adresleyelim.

delege += Carpma;

Bir delege aynı anda birden fazla metodu adresleyebilir. Yukarıda gördüğümüz gibi. “+= ” operatörü ile metod eklenirken, ” -= ” operatörüyle metod çıkartılabilir.

Eğer yukarıdaki kod bloğunu derleyip çalıştırırsanız ne olur? Sanıyorsunuz ki, delegemizin içinde iki metod var ve ikiside çalıştırılacak.Yani önce Toplama metodu çalıştırılıp 5 sonucunu verecek, ardından Carpma metodu çalıştırılıp 6 sonucu verilecek.Yada buna benzer durumlar olacak. Hepimizin takıldığı noktada burasıdır aslında ve sonuç olarak 6 döndürür çünkü delegeye bağlanan en son metod çalışır. En son bağlanan metod çarpma olduğu için çarpma metodumuz çalışcaktır.

HesaplaHandler delege = new HesaplaHandler(Toplama);
delege += Carpma;
delege -= Carpma;
MessageBox.Show(delege(2,3).ToString());

Bu kodu incelediğimizde delegemize önce Toplama metodu ekleniyor. Sonra Carpma metodu ekleniyor. En son olarak Carpma metodu delegeden çıkartılıyor. Yani burada Toplama metodu çalışacaktır. Kısaca özetlemek gerekirse ; A,B,C metodlarını sırasıyla delegemize bağlıyoruz.

En son metodumuz C olduğu için C metodumuz çalışacaktır.

C yi çıkardığımız da, B metodu çalışacaktır.

B yi çıkartırsak A metodu çalışacaktır.

Şimdide delegemiz içindeki tüm metodlarımız da sırasıyla gezebilmek için,delegate referansımız üzerinden GetInvocationList() metodunu kullanıyoruz.

private void Form1_Load(object sender, EventArgs e)
{
Hesapladelege = new HesaplaHandler(Toplama);
delege += Carpma;
Delegate[] metodlarımız = delege.GetInvocationList();
foreach (Delegate item in metodlarımız)
{
MessageBox.Show("Metodumuzun adı : " + item.Method.Name);
MessageBox.Show("Metodumuzun geri dönüş tipi : "+item.Method.ReturnType);
int sonuc = (int)item.DynamicInvoke(2, 3);
MessageBox.Show("Şuanki metodun sonucu : " + sonuc.ToString());
}
}

Yukarıda gördüğünüz geriye Delegate[] dizisi tipinden veriler dönüyor ve ben bunları Delegate[] metodlarımız dizisine alıyorum. Foreach döngüsüyle bu dizide dolaştırıyorum. Burada önemli bir nokta var. DynamicInvoke(),bu metod sayesinde o anda item referansına gelen metodu çalıştırabiliyoruz. Params tipinden değişken aldığı için metodların çalıştıracağı kadar parametre yazıyorum.

C# Delegate Event(Olay) Kullanımı

Bazen varsayılan metodlarımız yapacaklarımızı karşılamaz yada biz bambaşka bir şey yapmak istiyoruz. Bir durum, bir koşul olduğu zaman git o eventi çalıştır diye düşünebiliriz.

Şimdi formumuza bir Button nesnesi koyalım ve Click Eventına aşağıdaki şekilde ulaşalım.

private void Form1_Load(object sender, EventArgs e)
{
buttonTiklama.Click += new EventHandler(Tiklama);
}
void Tiklama(object sender, EventArgs e)
{
}

Click olayı Control sınıfı içinde tanımlanmış bir Event’tır. O sınıf içerisinde aynı zamanda Click event’inin oluştuğu sürekli kontrol edilmektedir. Eğer o sınıf, Click event’inin oluştuğunu tespit ederse , ” += ” ile o event’a bağladığım metod çalışacaktır. Ama o sınıf benim bu metodu yazdığımı bilmeyecektir. İşte bunu haberdar etmek için, bu sınıftaki metodu çalıştırabilmek için EventHandler kulanılıyoruz.

Şimdi bir class’taki metodu başka bir class’a bağlamayı görelim.

class SayiKontrol
{
public delegate void SayiKontrolEtHandler();                          //Delegate oluştu
public event SayiKontrolEtHandler SayiDurumu;                         // delegate Event yarattık
//Dikkat edin delegate ve event’ın isimleri aynı olmalıdır.
int sayi;
public int Sayi
{
get{return sayi;}
set{sayi = value;
if (sayi<10)
{
//event gelsin
}
}
}
}

Not: Eventların tipi,kendisine metod bağlayacak delegenin tipinden olur.

class SayiKontrol
{
public delegate void SayiKontrolEtHandler();
public event SayiKontrolEtHandler SayiDurumu;
int sayi;
public int Sayi
{
get{return sayi;}
set{sayi = value;}
if (sayi < 10)
{
if (SayiDurumu != null)
{
SayiDurumu();              // SayiDurumu null ise SayiDurumu eventini çağıracak
}
}
}
}
}

Şimdi bu eventi bağlayalım

private void Form1_Load(object sender, EventArgs e)
{
SayiKontrol nesne = new SayiKontrol();  // nesneyi yarattık
nesne.SayiDurumu += new SayiKontrol.SayiKontrolEtHandler(kontrol);
// SayiKontrolEtHandler delegesi bağlandı
nesne.Sayi = 15;
}
void kontrol()
{
MessageBox.Show("Sayi özelliği 10’dan küçük olamaz");
}

Bu yazımızda Delegate nedir ve Delegate Eventi gördük. Bir sonra ki yazımızda görüşmek üzere. Hoşçakalın..

hakkımdaki her şeyi bu blogda bulabilirsin. Haydi sende bir göz gezdirmeye ne dersin?

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir