C# - Delegate Kullanımı

Bu konuyu okuyanlar

Samet UCA

Profesör
Katılım
3 Ağu 2012
Mesajlar
3,293
Reaksiyon puanı
2,922
Puanları
113
C# programlama dilinde delegate kullanamını araştırırken bir arkadaştan yardım aldım.
Bu konuyla ilgili yaptığım araştırmalarda örneklerin alıntı ve açıklayıcı olmadığını gördüm.
Bu sebep ile delegate kullanımının tamamen iş yükü olduğunu düşünürken bir arkadaşım bu konuyla ilgili güzel bir açıklama yaptı.
Bu açıklamanın çok daha fazla kişiye ulaşması adına burada paylaşıyorum. Eğer C# dili ile ilgileniyorsanız bu konu size bir nebze fayda sağlayacaktır.

Bir delege (delegate) , bir metoda referansta bulunan bir nesnedir kabaca ve bir metodu encapsulationetmenin yöntemidir.Yani siz bir delege oluşturduğunuz vakit , bir metodun referansını tutan bir nesne oluşturuyorsunuz , tutucu tabiri de burdan geliyor sanırım Türkçemize.
Biraz referans a deyinmek gerekirse , bir nesneye referans aslında o nesnenin bellekte ki adresidir.Her bir metodun bellekte fiziki olarak bir konumu vardır. İşte bu konum yada adres bir delegeye atanabilir ve artık bu metot bir delege ile çağrılabilir.
Şimdi , senin fazladan iş yükü olarak gördüğün delege yi , ben başlıca büyük bir avantajıyla senin gözünde biraz yükselteyim :) . Hazırsan başlıyoruz , heyecanlı kısımlar başlıyor.
Programın çalışması esnasında , delegenin referansta bulunduğu metodu değiştirmek sence nasıl olur ? Farklı bir metoda referans vermek , farklı bir metodu çağırabilmenin ta kendisi değil mi sence ? Sonuç ney peki , ne olacak ki böyle olunca ? Sonuç şu , aynı delegeyle , çalışma anında , dikkatinizi çekeyim derleme anında değil , çalışma anında/çalışma zamanında (runtime) çalışacak metodu belirleyebiliyorum /değiştirebiliyorum. İşte bu delegelerin bize sunduğu başlıca büyük bir avantaj.
Bu gibi durumlarda kullanımına örnek verelim , bu saye de , ne gibi durumlarda kullanılır soruna da , ara ara cevap bulmuş oluruz.
Forvetleri yöneten tek bir hocamız olsun futbol maçında , işte bu bizim delegate imiz olacak , hoca 3 tane komut verdiğini varsayalım maç esnasında , bunlar da işte metotlarımız olacak. Maç esnasında (program çalışma sırasında) , rakibin atağına göre (kullanıcının programda davranışına göre) , komutları hoca (metotları delegate) değiştirecek.

C#:
delegate void ForvetYonet(string name);
class Forvet
{
    public static void DefansaGit(string name)
    {
        Console.WriteLine(name + " Defansa yardıma gel");
    }
    public static void HucumaDon(string name)
    {
        Console.WriteLine(name + " Yerime dön");
    }
    public static void OrtaSahayaGel(string name)
    {
        Console.WriteLine(name + " Orta sahada pas trafiğine dahil ol");
    }
    static void Main()
    {
        ForvetYonet forvetYonet = new ForvetYonet(DefansaGit);
        forvetYonet("Gomez");
        forvetYonet("Cenk");
        forvetYonet = new ForvetYonet(OrtaSahayaGel);
        forvetYonet("Cenk");
        forvetYonet("Dembaba");
        forvetYonet = new ForvetYonet(HucumaDon);
        forvetYonet("Gomez");
        Console.ReadLine();
    }
}

1.png


forvetYonet e ne zaman çağrılırsa , o anda hangi metoda referansı varsa , o metot çalıştırılır.Böylece hangi metodun çalışacağına derleme anında değil , çalışma anında karar verilmiş olur.

Delegenin bir başka heyecan veren kullanım durumu ise , çoklu çağrı (multicasting) dır.
Çoklu çağrı kabaca , bir delegenin çağıracağı metotları , bir çağrı zinciri şeklinde tutabilmesi / oluşturabilmesidir.Zincire , += operatörü ile bir metot eklerken , -= ilede zincirden metot çıkartılır.
Bu yöntemle oluşturduğumuz Delege Zincirleri güçlü bir yöntemdir / mekanizmadır ve bu mekanizmanın C sharp ta olaylar (events) ler ile beraber kullanıldığı bir kullanım durumu vardır , onuda müsait bir zamanda farklı bir cevapta yazmayı düşünüyorum.
Şimdi bu kullanım durumuna bir örnek verelim , üstteki cevabımda ki uygulamayı , bu kullanım durumunda da kullanalım.Kodlara açıklamalar koydum onlar yeterli olur diye düşünüyorum;

C#:
class Forvet
{
    public static void DefansaGit(string name)
    {
        Console.WriteLine(name + " Defansa yardıma gel");
    }
    public static void HucumaDon(string name)
    {
        Console.WriteLine(name + " Yerine dön");
    }
    public static void OrtaSahayaGel(string name)
    {
        Console.WriteLine(name + " Orta sahada pas trafiğine dahil ol");
    }
    static void Main()
    {
        //Delegateleri oluşturmak
        ForvetYonet forvetYonet;
        ForvetYonet defansaGit = new ForvetYonet(DefansaGit);
        ForvetYonet hucumaDon = new ForvetYonet(HucumaDon);
        ForvetYonet ortaSahayaGel = new ForvetYonet(OrtaSahayaGel);
        //çoklu çağrı (multicasting) hazırlamak
        forvetYonet = DefansaGit;
        forvetYonet += HucumaDon;
        //çoklu çağrı (multicasting) hazırlamak
        //cenk multicasting zincir sırasi gereği önce defansa gidecek
        //sonra hücuma dönecek
        forvetYonet("Cenk");
        //çoklu çağrı (multicasting) de bazı metotları çıkarıp
        //zincire yeni metot ekleme
        forvetYonet -= DefansaGit;
        forvetYonet += OrtaSahayaGel;
        forvetYonet += HucumaDon;  
        forvetYonet("Cenk");
        Console.ReadLine();
    }
}

Bu mekanizmanın çıktısı da bu şekilde olacaktır ;

Kod:
Cenk Defansa yardıma gel
Cenk Yerine dön

Kod:
ilk çağrı forvetYonet("Cenk");

Kod:
Cenk Yerine dön
Cenk Orta sahada pas trafiğine dahil ol
Cenk Yerine dön

Kod:
ikinci çağrı forvetYonet("Cenk");
Kod:

Delegelerin bir başka kullanımı durumu ise , delege üzerine kurulan ve C sharp ın bir başka güzel özelliği olan olaylardır(events). Kabaca olay(event) , bir etkinliğim, bir faaliyetin oluştuğunu / meydana geldiğini bildiren otomatik bildirge mekanizmasıdır.
Bu mekanizma şöyle çalışır. Olayla ilgilenen event nesnesi , olayla ilgili olay yöneticilerini kayıt altına alır. Bir nevi bir olay olma durumuna karşı önceden yapılacak adımları belirler. Olay meydana geldiğin de ise , kayıt altında tuttuğu ne kadar olay yöneticisi(event handler) varsa hepsini çağırır.
Hemen bir örnek yapalım daha iyi anlaşılması için , bir event nesnemiz üzerinden , bir olay meydana geldiği anda iki tane event handler çağıralım. Genelde Türkçe kaynaklarda olay yöneticileri çağrılırken , olayı ateşle tabiri kullanıldığından , benim de aklıma yangın olayı geldi gerçek hayattan , bu yüzden iki handlerımıda yangın söndürme araçları olarak seçtim

C#:
delegate void TestEventHandler();
// Olay Sınıfı.
class EventTest
{
    public event TestEventHandler SomeTestEvent;
    // Olayı ateşlemek.  
    public void OnSomeTestEvent()
    {
        SomeTestEvent?.Invoke();
    }
}
class EventTestDemo
{
    // Olay(Event) Yöneticisi  
    static void Handler()
    {
        Console.WriteLine("İtfaiye Aracı Çağrıldı");
    }
    // Olay(Event) Yöneticisi  
    static void Handler2()
    {
        Console.WriteLine("Yangın Söndürme Helikopteri Çağrıldı");
    }
    public static void Main()
    {
        EventTest evt = new EventTest();
        // Handler() ı Olaylara (olay listesine/zincirine) ekle.    
        evt.SomeTestEvent += new TestEventHandler(Handler);
        // Handler2() yi Olaylara (olay listesine/zincirine) ekle.    
        evt.SomeTestEvent += new TestEventHandler(Handler2);
        // Olayı(Eventi) Ateşle.
        //!!!Acil durum :)
        //Tüm olay yöneticilerini çağır    
        evt.OnSomeTestEvent();
        Console.ReadLine();
    }
}

2.png

Yukarıdaki 3 örnek silsilemizi toparlayacak olursak , yukarda ki örnekler sadece kullanım durumlarına örnek. Yani aslında hep delegelerin nasıl yapıldığı na , kullanım durumlarına cevap.
Peki delegelere neden ihtiyaç duyarız , delegeye neden gerek var sorularına da cevap vererek tamamlayalım.
C sharp ta Delegelere başlıca iki nedenden ötürü başvurulur.
1)Delegeler sayesinde çağrılacak metot derleme zamanın da değil de , çalışma zamanın da seçilir.
2)Olaylar(events) , delegeler üzerine inşa edilerek kullanılır.
 

Son mesajlar

Üst