Bir etkinliği gönderen her zaman genel bir Nesne olmalı mı?


10

C # 'daki olayları programlarken, şu şekilde bir temsilci oluşturmanız tavsiye edilir :

delegate XEventHandler(object sender, XEventArgs e);

Sorum delegenin ilk argümanında object sender. Her zaman jenerik olmak zorunda objectmı? Bir gönderene sahip olmak objecther zaman buna benzer bir kodla sonuçlanır.

val = ((ConcreteType)sender).Property;

veya daha ayrıntılı,

ConcreteType obj = sender as ConcreteType
if (obj != null) { ... }

Güçlü yazılan gönderenlere karşı yapılan bir argüman, diğer nesnelerin olay hakkında endişelenmeden olayı iletebilmesidir . Bu GUI ortamlarında mantıklı gelse de, GUI dışında fayda sağlayabileceğinden emin değilim.

Gönderenin sınıfı her zaman biliniyorsa (en azından soyut bir sınıf olarak)? Örneğin, ListChangedsoyut bir Listsınıfta bir olay uyguluyorsam ve diğer sınıflar bunu devralacaksa (örn LinkedList. ArrayList), Temsilci türünü bir gönderenle tanımlamak doğru Listmudur?

delegate ListChangedEventHander(List sender, ListChangedEventArgs e);

Yoksa konvansiyonel olanı object senderdaha spesifik bir türe dönüştürmenin bir dezavantajı olur mu?

Yanıtlar:


10

Bu noktada, çoğunlukla (oldukça güçlü) bir sözleşmedir. Yani, bu kurala uymayan bir kütüphane yazmanız garip olacaktır.

Olay Tasarım Kuralları ki:

DO kullanımını objectolay işleyicisi ilk parametrenin türü olarak ve diyoruz sender.

Bununla birlikte, mevcut rehberliğin etkinlikler için kendi özel temsilcinizi tanımlamamanız gerektiğini, ancak EventHandler<T>mümkünse bunun yerine kullanmanız gerektiğini söylediğini unutmayın .

Tasarıma gelince, aynı zamanda olayın orijinal tasarımcısı tarafından başlangıçta öngörülmeyen bağlamlarda bile olay işleyicilerinin yeniden kullanılmasını teşvik ettiğini tahmin ediyorum.


2
Ahhh ... Microsoft'un kurallarını herkese uygulanabilecek kadar genel yapmaya karar vermesi, herkesin kurallarına uymasının iyi bir fikir olduğu anlamına gelmiyor. Oranlar, "herkes" in milyonlarca geliştirici tarafından kullanılmak üzere kod yazmadığı anlamına gelecektir. Ben sağladığınız bağlantıdan önerileri yaklaşık 2/3 's creded.
Dunk

Doğruyu söylemek gerekirse, bu "kılavuz" aşağı yukarı Windows API'nin Macarca gösterimi gibi geliyor. Parlak biri gerçekten iyi bir nedenden dolayı başladı ve sonra herkes onu kötüye kullanmaya başladı. Bir kılavuz olduğunda, bu kılavuzun arkasında iyi bir neden olsa iyi olur. Ya ben bu kılavuz sebebi olduğunu düşünüyorum System.Windows.Formsad olaylar en çok kullanılan yerdir ve bu abone olmak mantıklıydı Clickdurumunda Buttonya da CheckBox. Böylece gönderici ihtiyacı genel olması. ...
sampathsris

... Ama diğer, daha spesifik, içerdiği işlevsellik alanlarına gelince, gönderenin genel bir sınıf olması gerekmeyebilir. Tekrar Lists sınıf hiyerarşisi örneğime bakın .
sampathsris

11
@Dunk: İşte mesele bu. Bu kılavuz, öncelikle başkaları tarafından tüketilen kodla ilgili olan Çerçeve Tasarım Yönergeleri'nden gelmektedir . En iyi çözüm olduğu için değil, en az şaşırtıcı olduğu için. Bir çerçeve için en iyi seçenek budur . Daha küçük kütüphaneler için, kullanım örneği iyi belirlenmişse, daha az rehberlik uygulanabilir. Microsoft açıkça kitabın başında söylüyor.
Magus

1
Cevabı tartışmıyorum, hatta onayladım çünkü saygın bir kaynaktan geliyor. Sadece yönergeleri kullanmayacağımı söylüyorum. Bir etkinliğin belirli verileri göndermesi gerekiyorsa, yalnızca belirli verileri gönderirim. Ayrıca, etkinlik özelliği, nasıl kullanılmak üzere tasarlandıklarını kullanırsanız iyi çalışır.
Dunk

0

Tavsiyenin nedeni, mevcut kodda ve özellikle genel arayüzde mutlaka değişiklik yapılmasını gerektirmeyen gelecekteki değişikliklere izin vermesidir.

Etkinlik mekanizması yine de "VB6" tarzı etkinlikler için kullanılabilir, ancak imzayı değiştirmeniz gerekirse (veya daha da kötüsü: aynı etkinliklerin yeni sürümlerini oluşturmanız gerekirse) mevcut tüm tüketicileri değiştirmeniz gerekir. Önerilen yaklaşımla, yeni öğeler mevcut olanlardan miras kaldığı sürece, mevcut kodu düzeltmeden imzayı güncelleyebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.