Delegate ve Event
delegate ve event, Observer ve Observable örüntüsüne uygun olarak kullanılabilir.
Delegate C'deki function pointer, C++'taki std::function veya Java'daki tek metodu olan bir interface olarak düşünülebilir. Event ise Function Pointer listesi olarak düşünülebilir. Bu ikili aşağıdaki gibi tanımlanıyorlar.
Delegate tanımı
Event Tanımlama
Şöyle yaparız
C# 2.0'dan önce aşağıdaki gibi delegate metodu new'lenerek yapılıyordu.
Delegate eklenmemiş event nesnesi null nesne gibi çalışır. Dolayısıyla her zaman null kontrolü yapmak gerekir.
Event'i çağırırken kopyasını alıp çağırmak thread safe olması için yeterli.
C#'ta hazır gelen Action Delegate, Function Delegate sınıfları var.
Kendi Event Hiyerarşim
Şöyle bir hiyerarşi kurduğumuzu olsun
Daha sonra delegate'ı bir sınıf ile sarmayalım.
Bir de Observer yazalım.
delegate ve event, Observer ve Observable örüntüsüne uygun olarak kullanılabilir.
Delegate C'deki function pointer, C++'taki std::function veya Java'daki tek metodu olan bir interface olarak düşünülebilir. Event ise Function Pointer listesi olarak düşünülebilir. Bu ikili aşağıdaki gibi tanımlanıyorlar.
Delegate tanımı
public delegate void MyventHandler(object sender, EventArgs e);
Delegate tanımında ilk parametrenin sender olması, Microsoft tarafından tavsiye edilen şey. Ne faydası var ben de tam anlamadım.Event Tanımlama
Şöyle yaparız
public event MyEventHandler SomethingHappened;
Event kayıtlı tüm delegate'leri aynı parametre ile çağırır. Açıklaması şöyleEvents are an extremely convenient way for an object to collate 'handler' delegate methods, and then to be able to call them all with a set of parameters.Event Listesine Ekleme Yapma
C# 2.0'dan önce aşağıdaki gibi delegate metodu new'lenerek yapılıyordu.
watcher.Created += new FileSystemEventHandler(OnChanged);
Ancak yeni kodlarda buna gerek yok.watcher.Created += OnChanged;
Boş Event NesnesiDelegate eklenmemiş event nesnesi null nesne gibi çalışır. Dolayısıyla her zaman null kontrolü yapmak gerekir.
if (MyEvent != null)
MyEvent(this, e);
Bazıları böyle çalışmayı sevmiyor. Bu kontrolü yapmamak için event'i ilklendirirken boş bir delegate ekliyorlar. Bu kodun çok az bir performans etkisi dışında bir kötü bir tarafı yok.public event EventType MyEvent = delegate {};
Event ve Thread Safe ÇalışmaEvent'i çağırırken kopyasını alıp çağırmak thread safe olması için yeterli.
var handler = Complete;
if(handler != null)
{
handler();
}
Hazır Delegate SınıflarıC#'ta hazır gelen Action Delegate, Function Delegate sınıfları var.
Kendi Event Hiyerarşim
Şöyle bir hiyerarşi kurduğumuzu olsun
public class Event {}
public class EventA : Event {}
public class EventB : Event {}
Bu hiyerarşi için bir delegate tanımlayalım
delegate void HandlerDelegate<TEvent>(TEvent ev) where TEvent : Event;
class EventManager
{
Dictionary<Type, Delegate> delegateMap = new Dictionary<Type, Delegate>();
void Dispatch<TEvent>(TEvent ev) where TEvent : Event
{
Delegate d;
if (delegateMap.TryGetValue(typeof(TEvent), out d))
{
var handler = (HandlerDelegate<TEvent>)d;
handler(ev);
}
}
void Register<TEvent>(HandlerDelegate<TEvent> handler) where TEvent : Event
{
delegateMap.Add(typeof(TEvent), handler);
}
}
public class EventListener
{
public EventListener(EventManager evtMgr)
{
evtMgr.Register<EventA>(this.HandleEventA);
evtMgr.Register<EventB>(this.HandleEventB);
}
public void HandleEventA(EventA ev)
{
//... do stuff
}
public void HandleEventB(EventB ev)
{
//... do stuff
}
}
Hiç yorum yok:
Yorum Gönder