İçindekilerGirişİndex
YukarıİlkÖncekiSonrakiSon
Geriİleri
Yazdır
Zafer Teker
tekzaf@yahoo.com

C#.Net Delegate ve Event Kullanımı

Bu yazıda C#.Net'te delegate'in ve event'in ne olduğu ve nasıl kullanılacağı anlatılmaktadır. Basit örneklerle delagate ve event açıklanmaktadır.

Delegate

Bir olay gerçekleştiğinde birden fazla fonksiyonu çağırmak istediğinizi düşünelim. Örneğin kullanıcı bir düğmeye tıkladığında birden fazla method'un otomatik olarak çağrılmasını istiyorsunuz. Bunun için delagate kullanabilirsiniz. Burada amaç şu. Bir olay olduğunda birden fazla yere bu olayı bildirebilmek. Bu olay ile ilgilenler delegate ile olaydan haberleri olur.

delagate olarak bir method tanımlanır. Bu method aslında temsilcidir. Bir olay olduğunda siz delegate method'unu çağrırsınız. delegate method'una kendisini ekleyen method'lar otamatik olarak çağrılırlar. Aşağıda basit bir delegate methodu yaratıyoruz.

public delegate void foo();

foo methodu delagate method'udur ve görüldüğü gibi body'si (içeriği) yoktur.

Class'ın içinde herhangi bir olay olduğunda foo() method'unu çağırabilirsiniz.

//Bir olay oldu. foo delagate method'unu çağır
foo();

yukarıda görüldüğü gibi delegate method'lar normal bir method gibi çağrılabilmekte. Ama foo mehodu hiçbir şey yapmamaktadır. foo methodu delagte methodudur. Eğer kendisie bir method kayıt edilmişse o methodu çağıracaktır. Örneğin bir test() methodumuzu şu şekilde ekleyebiliriz.

...
foo x=new foo(test);
...

public void test(){
	Console.Write("OK");
}

Bir x foo delagate'i yarattık. Bu delagate'e test method'unu verdik. test method'u console'a sadece OK yazar. Herhangi bir yerde foo methodu çağrıldığında test() methodu çağrılmış olur.

Birden fazla method'u bir delagate method'a ekleyebilirsiniz.

...
foo x=new foo(test);
x+=new foo(test2);
x+=new foo(test3);

Yukarıda test,test2 ve test3 method'larını ekledik. foo çağrıldığında bu üç method'da çağrılacak.

delagate method'ları parammetre'de alabilir. Örneğin foo method'u bir string paramtresi alabilir. Eğer strng paramtresi alıyorsa eklenen tüm method'lar aynı şekilde paramtre alması gerekir.

Basit bir uygulama olsun. Console'da kullanıcıdan bir giriş yapıldığı zaman üç faklı method çağıralım. Bu method'lar kullanıcıya bir mesaj vermektedir.

DelegateTestApp.csİndir Göster Gizle Kopar Satır Gizle Satır Göster
  1 using System;
  2 namespace Test{
  3     class DelegateTestApp{    
  4     public DelegateTestApp(){
  5       testDelegate d=new testDelegate(ok);
  6       d+=new testDelegate(ok2);
  7       d+=new testDelegate(ok3);
  8       string i=Console.ReadLine();
  9       d(Convert.ToInt32(i));
 10     }    
 11     public delegate void testDelegate(int a);
 12     public void ok(int i){
 13       Console.WriteLine(i+" girdiğiniz için teşekkürler");
 14     }
 15     public void ok2(int i){
 16       Console.WriteLine(i+" sayısını girdiniz.");
 17     }
 18     public void ok3(int i){
 19       Console.WriteLine(i+" sayısını girdiniz galiba.");
 20     }
 21         public static void Main(string[] args){
 22       new DelegateTestApp();
 23     }
 24   }
 25 }

Kullanıcı bir sayı girer. Girilen sayı ile d delagati'i çağrılır. d dalegatine ok,ok2,ok3 method'ları eklendiğinden bu method'lar çağrılmış olur. Sonu olarak ekranda bu üç method'un yazdığı yazılar gözükür.

Event

Event'ler dalegate'lere benzer. Ancak daha iyi özelliklere sahiptir. Event'ler genellikle GUI konponentleri için kullanılan bir kavram. Örneğin bir düğmenin tıklanması bir event oluşturur. Veya farenin hareket etmesi, tıklama bu tür "olay"lar bir Event oluştururlar. Aynı şekilde herhangi bir özellikleki değişme için siz bir event yaratabilirsiniz. Bu event'i dinleyenler event'in oluşundan haberdar olur. Yukarıdaki örneğe göre düşünürsek. Kullanıcının bir sayı girmesi bir event oluşturabilir. Oluşan event dinleyicilere bildirilir.

EventTest.csİndir Göster Gizle Kopar Satır Gizle Satır Göster
  1 using System;
  2 namespace Hello
  3 {
  4   public class EventTest
  5   {
  6     public delegate void testDelegate(int a);
  7     public event testDelegate testEvent;
  8     public EventTest(){
  9       testEvent+=new testDelegate(ok);
 10       testEvent+=new testDelegate(ok2);
 11       testEvent+=new testDelegate(ok3);
 12       string i=Console.ReadLine();
 13       testEvent(Convert.ToInt32(i));
 14     }    
 15     public void ok(int i){
 16       Console.WriteLine(i+" girdiğiniz için teşekkürler");
 17     }
 18     public void ok2(int i){
 19       Console.WriteLine(i+" sayısını girdiniz.");
 20     }
 21     public void ok3(int i){
 22       Console.WriteLine(i+" sayısını niye girdin kardeşim");
 23     }
 24     public static void Main(string[] args){
 25       new EventTest();
 26     }
 27   }
 28 }

Bu örnek ile daha önceki örnek arasında fazla bir fark yok.

public event testDelegate testEvent;

şeklinde bir event yaratıyoruz.

testEvent+=new testDelegate(ok);
testEvent+=new testDelegate(ok2);
testEvent+=new testDelegate(ok3);

şeklinde ok,ok2 ve ok3 method'larını kaydediyoruz.

testEvent(Convert.ToInt32(i));

şeklinde çağırdığımız an ok,ok2 ve ok3 method'ları çağrılmış olur.

Genellikle event dalegate method'larının

(object sender,System.EventArgs e)

şeklinde olduğunu görürsünüz. Bu standart bir işlemdir. sender olayın hangi nesne tarafından üretildiği bilgisini verir. Örneğin iki düğmeyi birden dinlediğinizi düşünün. Bir düğmeye tıklanma olayı olduğunda sizin bir method'unuz çağrılsın. Sizin method'unuz hangi düğme tarafından çağrıldığınızı nerden bilebilir. Bunun için object sender paramtresi gösderilir. Diğer bir soru düğmenin üstündeki yazıya ihtiyacınız olduğunda nasıl alabilirsiniz. Veya bir fareye tıklanma olayı oldu. Farenin tıklandığı x,y noktasını nasıl alabilirsiniz. Bunuda EventArgs class'ını extend eden bir class ile yapabilirsiniz. EventArgnesnesinden gerekli bilgileri alınabilir.

yukarıdaki örneği object sender ve System.EventArgs e parametreleri ile yapalım.

EventTestParametreli.csİndir Göster Gizle Kopar Satır Gizle Satır Göster
  1 using System;
  2 namespace Hello
  3 {
  4   public class EventTestParametreli
  5   {
  6     public delegate void testDelegate(object sender,TestEventArgs args);
  7     public event testDelegate testEvent;
  8     public EventTestParametreli(){
  9       testEvent+=new testDelegate(ok);
 10       testEvent+=new testDelegate(ok2);
 11       testEvent+=new testDelegate(ok3);
 12       string i=Console.ReadLine();
 13       int sayi=Convert.ToInt32(i);
 14       testEvent(this,new TestEventArgs(sayi));
 15     }    
 16     public void ok(object sender,TestEventArgs args){
 17       Console.WriteLine(args.Sayi+" girdiğiniz için teşekkürler");
 18     }
 19     public void ok2(object sender,TestEventArgs args){
 20       Console.WriteLine(args.Sayi+" sayısını girdiniz.");
 21     }
 22     public void ok3(object sender,TestEventArgs args){
 23       Console.WriteLine(args.Sayi+" sayısını niye girdin kardeşim");
 24     }
 25     public static void Main(string[] args){
 26       new EventTest();
 27     }
 28     public class TestEventArgs : EventArgs{
 29       private int sayi;
 30       public TestEventArgs(int sayi){  
 31         this.sayi=sayi;
 32       }
 33       public int Sayi{
 34         get{return sayi;}
 35         set{sayi=value;}
 36       }
 37     }
 38   }
 39 }

public class TestEventArgs : EventArgs{
	private int sayi;
	public TestEventArgs(int sayi){	
		this.sayi=sayi;
	}
	public int Sayi{
		get{return sayi;}
		set{sayi=value;}
	}
}

şeklinde bir inner class yarattık. Bu class ile girilen sayıyı dinleyen method alabilir. bu class'ta sayı dışındaki başka bilgiler de tutabilirsiniz. Örneğin kullanıcı ne zaman giriş yaptı, hangi işletim sisteminden giriş yaptı vs.. gibi bilgiler de tutulabilir. delegate method'uda

public delegate void testDelegate(object sender,TestEventArgs args);

şeklinde tanımlanır. ve TestEvent

testEvent(this,new TestEventArgs(sayi));

şeklinde çağrılmaktadır.

Son Söz

Yukarıdaki örnekler sadece konunun anlaşılması içindir. Aslında olayı dinleyen ile yayınlayan aynı class olmaz. Bizim örneklerimizde hep Event yaratan class aynı zamanda event'i dinliyordu. ok,ok2 ve ok3 methodları başka bir class'ta olması gerekir. Ancak bunu kolayca yapabilirsiniz. Çok bir şey değiştirmeye gerek yok.

Dosya Listesi

İçindekilerGirişİndex
YukarıİlkÖncekiSonrakiSon
Geriİleri
Yazdır