C# Delegate(Temsilci) ve Event(Olay) Kullanımı
Event
Tanım olarak çok ayrıntıya girmek istemediğim bir konudur.Bir buton nesnesine farenin sol tuşuyla tıkladığımızda,bir textbox nesnesine bir karakter girdiğimizde ya da fareyle combobax daki elemanlardan birini seçtiğimizde bir olay gerçekleşir.İşte bu durumların hepsi bir olaydır.
Ş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)
{
button1.Click += new EventHandler(Tiklandi);
}
void Tiklandi(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 olayının meydana gelip gelmediği de sürekli kontrol edilmektedir.Eğer o sınıf, Click olayının oluştuğunu tespit ederse , ” += ” ile o olaya bağladığım metod çalıştırılacaktır.Halbuki o sınıf benim Click e bağladığım bu sınıftaki metottan haberdar olmayacaktır.O sınıfı, bu sınıftaki metottan haberdar etmek için,bu sınıftaki metodu çalıştırabilmek için yine o sınıfta tanımlı olan delegeyi(EventHandler) kullanıyoruz.
Burada anlatmak istediğim pek aydınlatıcı ve hatta anlaşılır olmamış olabilir.Bir sonraki sayfada asıl mevzuya giriyorum.Bir Classtaki Event a, başka bir Classtaki metodu bağlayabilecek olan delegeyi oluşturacağım.

Delegeler konusunu sizin anlatımınızla öğrendim.
Teşekkür ederim.
Faydalı olabildiysem ne mutlu bana,
Saygılarımla 🙂
Anlaşılır bir anlatım olmuş.
Emeğinize sağlık…
Yorumunuz içinde iltifatınız içinde teşekkür ederim..
cidden çok sade bi anlatım olmuş.. sayfa sayfa karışık anlatımlarla kıyaslayınca da çok kolay anlaşılabilir bi not olmuş. elinize sağlık
Merhaba Ahmet,
Böyle güzel yorumlarınız eşliğinde insan yaptığından ayrı bir huzur tadıyor 🙂
Teşekkürlerimi sunarım, eksik olmayın..
Tşk Ederim 3 sayfanda çok güzel anlatmışsın 🙂
ilk önce başka sitelerde okuyup anlamadığım için sinirliydim
o sinirle okuyunca senin yazınıda anlamadım şimdi tekrar okuyunca çözdün olayı teşekkürler
Aman sakin 🙂
Makale için teşekkürler. kesinlikle bir şeylerin daha iyi anlaşımlasına vesile oldunuz. 🙂
küçük bir soru. event’i classın yapıcı metot’unda fırlatmak istediğimide null dönüyor ve hata veriyor nedeni nedir acaba?
——————————————————————————————————–
class Class1
{
public delegate void sayiSay(string metin);
public event sayiSay sayiSayildi;
internal Class1()
{
string sayiSay= “Sayı”;
for (int i = 1; i ” + i.ToString());
}
}
}
———————————————————————————————————
Bu classı bir formda veya buton altında aşağıda ki oluşturun . Hata verecektir.
———————————————————————————————————
private void Form1_Load(object sender, EventArgs e)
{
Class1 cs = new Class1();
cs.sayiSayildi+= cs_sayiSayildi;
}
void cs_sayiSayildi(string metin)
{
MessageBox.Show(metin);
}
———————————————————————————————————
Cevaplarsanız memnun olurum 🙂
Merhaba,
Yazmış olduğunuz Class1 in Constructer’ında ne yaptığınız net değil. Ama dediğiniz gibi eventı yapıcı metotda fırlatıyorsanız eğer, ilgili sınıftan nesne üretildiği anda event fırlatılacak lakin olaya bağlı bir metod bulunmadığı için hata alacaksınız. Yani cs.sayiSayildi += cs_sayiSayildi komutuna gelene kadar iş işten geçmiş olacak. Bu komuttan sonra olayı fırlatmanız sorunu çözecektir.
Saygılar…
evet eksik yazmışım 🙂
for döngüsünü de bir kenara bırakın 🙂 . yapıcı metotda direk eventi direk fırlattığımızı varsayalım. bu durumda ne olursa olsun, daha nesne oluşturulurken eventi fırlattığımız için ve evente henüz bir metot bağlanmadığı için (çünkü henüz o satıra gelemedik) hata veriyor. bu durum da yapıcı metotda event tanımlayamayız diye anlıyorum ben.
ilginiz için teşekkürler.
Aynen öyle…
Tekrar bekleriz…
Tebrikler hocam. Çok açıklayıcı bir anlatım olmuş.
Teşekkürler dostum 🙂
Event kodunda mantık hatası var sanırım…
set edilmek istenen value ataması yapıldıktan sonra if kontrolüne giriyor. Yani set edilmek istenen sayı 10’dan küçük olursa yine set (atama) işlemi yapılacak ve ekrana “sayı özelliği 10dan küçük olamaz” mesajı yazdırılacak ama yinede sayı değişkenimiz 10’dan küçük değere sahip olacak.
Burada mantık hatası yok mu ? yani if koşulu ile kontrol edildikten sonra atama işlemi yapılması gerekmez mi ?
Merhaba Cüneyt Bey;
Mantıksal olarak dediğiniz gibi olması gerekmektedir 🙂 Ne hikmetse zamanında bu şekilde örnek kod yazmışım 🙂
Arada böyle oluyor. Nihayetinde aklın yolu bir. Haklısınız.
Çok güzel bir anlatım teşekkürler.
Farkli kaynaklarda delege ve eventlere birden fazla eklenince hepsinin calisacagi yaziyor.bunun nedeni c# surum farkiyla ilgili olabilir mi ? Yoksa fsrkli bir neden mi var acaba
Bir delegate eklenen tüm metotlar icra edilir, farkına varılmadan yanlış bir bilgi verilmiş sanırım. MessageBox.Show(delege(2,3).ToString()); ifadesini her bir metodun (Topla,Çarp) içerisine yazabilirseniz sonucu daha net bir şekilde alabilirsiniz.
Merhaba,
Dediğiniz gibi, delegate içerisindeki fonksiyonlar içerisinden MessageBox sınıfı çağrılabilir ve sonuç gösterilebilirdi. Lakin, bu makaleyi yazdığım yıllarda sanırım bu durumda okuduğum kaynaklar doğrultusunda ve ek olarak tarafımca yapılan tüm testler neticesinde edindiğim bilgiler bu kanıya varmama sebebiyet vermiştir. O dönem, .NET sürümünde olmayan bir özellik sonraki süreçte geliştirilmiş olabilir.
Evet…
ya da ben farkında olmaksızın yanlış bilgi vermiş olabilirim…
Nihayetinde katkılarınız için teşekkür ederim…
Daha fazla katkıda bulunmak istiyorsanız tabi ki de yapacağınız her türlü yönlendirme ve eklemelere açık olduğumu bilmenizi isterim.
Teşekkürler…
Sevgiler…
güzel
Gencay Abi merhaba öncelikle çok sade ve anlaşılır bir şekilde anlatmışsın herzaman ki gibi. O yüzden teşekkür ederim bu tarz makaleler için. Fakat şu konuda bir yanlışlık var. Makalede “Burada delegemize bağlanan en son metod Carp metodumuz olduğu için, o çalışacaktır.Yani Topla metodu çalışıp, ardından Carp çalışmayacaktır.” demişsin. Ama bu bilgi yanlış. Aslında iki metodu da çalıştırıyor ama en son ki metodun return ettiği değeri döndürüyor. Yukarıdaki Topla ve çarp metotlarının içine Console.WriteLine(“Topla çalıştı…”); gibi kod satırları yazarak görebilirsin.
Merhaba Alperen kardeşim.
Evet, o hatamı önceden uyaran arkadaşlar oldu. Bende yorumlarda yaptığımız istişareye istinaden içerikteki hatalı ifadeyi olduğu gibi bıraktım ki tartışmanın sebebi görülebilsin.
Bilgilendirmen için teşekkür ederim.
Sevgiler.
Merhaba
Gençay hocam. Sizi youtube platformunda da takip ediyorum. Sizden çok şey öğrendim. Makaleleriniz benim için daha da artı oluyor. Emekleriniz için teşekkür ederim
Merhaba,
Bol bol faydalanmanız dileğiyle…
Sevgilerimle…
Hocam anlatımız gayet anlaşıklı. Konuyu öğrenmiş oldum sadece birşeyi hala anlayamadım. Çoğunluklu olarak MVC üzerinden Web Projeleri geliştirmekteyin ara sıra Console ve Winformda kullanmışlığım oldu. Ama şimdiye kadar kendi projelerimdede hiç bir zaman delegate kullanmadım. Gerek duymadım diyebilirim. Yani en önemlisi demek istediğim metodun kendisini kullanıp gereken sonucu alabiliyorsak delegate neden kullanmalıyız. Kendinizde yazınızda
“İstesek x metodunu yukarıdaki gibi çağırıp çalıştırabiliriz” diye belirtmişsiniz
Peki bunu önemli yapan nedir ? Herhalde C# geliştiricileri bunu boşu boşuna dahil etmemişlerdir diye düşünüyorum. Yazıda buna değindiyseniz görmediysem şimdiden özür dilerim. Teşekkürler
Merhaba,
Güzel soru.
Delegate’in işlevselliği ihtiyaç noktalarında devreye farklı metotları dolaylı bir yolla sokabilmesinden gelmektedir. Böylece metotları runtime’da seçebilmemizi sağlamaktadır.
Normalde bir metodu compiler time’da bilinebilecek şekilde tetiklersiniz. Halbuki delegate’ler metotları anonim olarak çağırmanıza izin veren yapılar olduğundan dolayı, runtime sürecinde çağrılabilmektedirler. Böylece çağrılan metodun hangisi olduğunu bilemezsiniz!
Buradan anlıyoruz ki, delegate’ler işaret/temsil ettikleri metotları veri olarak gören yapılar olarak düşünülebilir. Haliyle bu veri olarak görülen metotları istediğiniz herhangi bir noktada işleyebilmektesiniz.
Peki hangi durumlarda delegate’ler ile temsil edilen metotları işlemeyi tercih ederiz? diye sorarsanız eğer;
delegate’lerden istifade edebiliriz.
Umarım cevabım meramınızı gidermeye yardımcı olmuştur.
Sevgilerimle…
Yazıda delege içerisinde bulunan tüm metotlar değilde sadece en son eklenen metod çalışıyor demişsiniz ama öyle değil bütün metotlar ekleme sırasına göre çalışıyor geri dönüş türleri varsa da en son eklenen metodun döndüğü değer dönülüyor.
Evet, bu durumu önceden yapılan yorumlarda da bazı arkadaşlarımızla istişare ederek kabullenmiş durumdayım.
Teşekkürler.
private void Form1_Load(object sender, EventArgs e) { IslemYapHandler delege = new IslemYapHandler(Topla); delege += Carp; 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()); } }Çalıştırdığımda ” ‘System.Int32’ türündeki nesne ‘System.Int16’ türüne dönüştürülemez.” hatası alıyorum.
Platform Visual Studio 2012 ve .Net Framework 4.5
Teşekkür ederim.
Hatayı hangi satır için veriyor?