Delegates ve Eventler
Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 43 / 70.
Bir delegate, bir metoda olan referansı temsil eden bir türdür. Bunu, veri yerine bir metodu tutan bir değişken olarak düşünün. Bu, metotları argüman olarak geçirmenize, koleksiyonlarda saklamanıza ve onları dinamik olarak çağırmanıza olanak tanır.
Bir delegeyi, referans verebileceği metot imzasını belirterek tanımlarsınız:
public delegate void Notify(string message);
public class Publisher
{
public void SendAlert(string msg) => Console.WriteLine("Alert: " + msg);
}
// Kullanım
Notify notifier = new Publisher().SendAlert;
notifier("System started"); // Alert: System startedOlaylar (Events), yayınla-abone ol (publish-subscribe) desenini uygulamak için delegeler üzerine inşa edilir. Bir sınıf bir olay tetikler ve diğer sınıflar bildirim almak için abone olabilirler. event anahtar kelimesi, delegenin nasıl kullanılabileceğini kısıtlar; aboneler yalnızca işleyiciler ekleyebilir veya kaldırabilir, olayı doğrudan tetikleyemezler.
public class Button
{
public event Action Clicked;
public void Click()
{
Clicked?.Invoke(); // Tüm aboneleri bilgilendir
}
}
// Abone olma
Button btn = new Button();
btn.Clicked += () => Console.WriteLine("Button was clicked!");
btn.Click(); // Butona tıklandı!+= operatörü bir işleyiciye abone olurken, -= aboneliği iptal eder. ?.Invoke() deseni, olayı yalnızca aboneler varsa güvenli bir şekilde çağırır. Olaylar; GUI uygulamaları, oyun motorları ve nesnelerin sıkı bağlılık olmadan değişikliklere tepki vermesi gereken her sistem için temeldir.
Görev
KolaySıcaklık her değiştiğinde aboneleri bilgilendirmek için delegeleri ve olayları (events) kullanan bir sıcaklık izleme sistemi oluşturalım. Bu, olayların çok zarif bir şekilde mümkün kıldığı klasik bir yayınla-abone ol (publish-subscribe) deseni örneğidir.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
TemperatureMonitor.cs:Monitoringad alanı (namespace) içinde, yayıncı (publisher) görevi gören birTemperatureMonitorsınıfı oluşturun. İzleyiciniz şunları yapmalıdır:- Mevcut sıcaklığı saklamak için özel (private) bir alana sahip olmalıdır
- Sıcaklık her güncellendiğinde tetiklenen,
Action<int>kullananTemperatureChangedadında bir olay (event) bildirmelidir - Ayarlayıcısının (setter) özel alanı güncellediği ve yeni sıcaklık değeriyle olayı tetiklediği bir
Temperatureözelliğine (int) sahip olmalıdır
?.Invoke()desenini kullanmayı unutmayın.Program.cs: Ana dosyanızda birTemperatureMonitoroluşturun veTemperatureChangedolayına iki farklı işleyici (handler) abone yapın:- Şunu yazdıran bir işleyici:
Alert: Temperature is now {value} degrees - Şunu yazdıran başka bir işleyici:
Logged: {value}
- Şunu yazdıran bir işleyici:
İki girdi alacaksınız:
- Birinci sıcaklık değeri (tam sayı)
- İkinci sıcaklık değeri (tam sayı)
Örneğin, girdiler 25 ve 30 ise, çıktı şu şekilde olmalıdır:
Alert: Temperature is now 25 degrees
Logged: 25
Alert: Temperature is now 30 degrees
Logged: 30Temperature özelliğini ayarlamanın tüm aboneleri otomatik olarak nasıl bilgilendirdiğine dikkat edin - izleyicinin kimin dinlediği hakkında hiçbir şey bilmesine gerek yoktur. Olay tabanlı (event-driven) yaklaşımın güzelliği de budur!
Kopya kağıdı
Bir delegate, bir metoda olan referansı temsil eden bir türdür; metotları argüman olarak iletmenize, koleksiyonlarda saklamanıza ve dinamik olarak çağırmanıza olanak tanır.
Metot imzasını belirterek bir delegate tanımlayın:
public delegate void Notify(string message);
public class Publisher
{
public void SendAlert(string msg) => Console.WriteLine("Alert: " + msg);
}
// Kullanım
Notify notifier = new Publisher().SendAlert;
notifier("System started"); // Alert: System startedEvent'ler (Olaylar), delegate'leri kullanarak yayınla-abone ol (publish-subscribe) desenini uygular. event anahtar kelimesi delegate kullanımını kısıtlar; aboneler yalnızca işleyiciler ekleyebilir veya kaldırabilir, olayı doğrudan tetikleyemezler.
public class Button
{
public event Action Clicked;
public void Click()
{
Clicked?.Invoke(); // Tüm aboneleri bilgilendir
}
}
// Abone olma
Button btn = new Button();
btn.Clicked += () => Console.WriteLine("Button was clicked!");
btn.Click(); // Button was clicked!Bir işleyiciye abone olmak için += ve abonelikten çıkmak için -= kullanın. ?.Invoke() deseni, olayı yalnızca aboneler varsa güvenli bir şekilde çağırır.
Kendin dene
using System;
using Monitoring;
class Program
{
public static void Main(string[] args)
{
// Girişi oku
int temp1 = Convert.ToInt32(Console.ReadLine());
int temp2 = Convert.ToInt32(Console.ReadLine());
// TODO: Bir TemperatureMonitor örneği oluşturun
// TODO: Şu metni yazdıran bir işleyiciye abone olun: "Alert: Temperature is now {value} degrees"
// TODO: Şu metni yazdıran başka bir işleyiciye abone olun: "Logged: {value}"
// TODO: Sıcaklığı temp1 olarak ayarlayın
// TODO: Sıcaklığı temp2 olarak ayarlayın
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici Dosyalarİsim Alanları ve YönergelerSınıf ve Nesnelere Giriş'this' Anahtar KelimesiMetotlar ve ParametrelerAlanlar ve ÖzelliklerYapıcı MetotlarNesne BaşlatıcılarÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (:) Sözdizimi'base' Anahtar KelimesiVirtual ve Override Anahtar KelimeleriSealed Sınıflar'object' Temel SınıfıÖzet - Çalışan Hiyerarşisi7İleri Düzey Özellikler
Operatör Aşırı Yüklemeİndeksleyiciler (this[])ToString() Geçersiz KılmaGenişletme MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişThread-Safe SingletonFactory KalıbıObserver Kalıbı (Olaylar)Strategy Kalıbı2Özellikler ve Statik Üyeler
Otomatik Uygulanan ÖzelliklerSadece Okunur/Yazılır ÖzelliklerStatik Alanlar ve MetotlarStatik Sınıflarİfade Gövdeli Üyeler5Polimorfizm ve Arayüzler
Derleme vs Çalışma Zamanı PolimorfizmiArayüz vs Soyut SınıfÇoklu ArayüzlerBelirgin ArayüzlerUpcasting ve DowncastingÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kalıtım yerine KompozisyonGenerics (Sınıflar ve Metotlar)Delegates ve EventlerAttributes ve ReflectionIDisposable ve using İfadesiDependency Injection Temelleri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı3Sınıf Mimarisi
Örnek vs Statik Veri'readonly' ve 'const' Anahtar KelimeleriDestekleyici Alanlar (Backing Fields)Özet - Banka Hesabı Yöneticisi6Kapsülleme
Erişim BelirleyicilerKapsülleme için ÖzelliklerVeri Gizleme UygulamasıDeğişmezlik KalıplarıÖzet - Öğrenci Kayıtları