Menu
Coddy logo textTech

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 started

Olaylar (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.

challenge icon

Görev

Kolay

Sı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: Monitoring ad alanı (namespace) içinde, yayıncı (publisher) görevi gören bir TemperatureMonitor sı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> kullanan TemperatureChanged adı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
    Olayı yalnızca aboneler olduğunda güvenli bir şekilde tetiklemek için ?.Invoke() desenini kullanmayı unutmayın.
  • Program.cs: Ana dosyanızda bir TemperatureMonitor oluşturun ve TemperatureChanged olayı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}
    Her iki işleyiciyi de abone yaptıktan sonra, girdiden gelen değerleri kullanarak sıcaklığı iki kez ayarlayın. Sıcaklığı her ayarladığınızda, her iki işleyici de yanıt vermelidir.

İ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: 30

Temperature ö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 started

Event'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
    }
}
quiz iconKendini test et

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