Haruskah pengirim acara selalu menjadi Objek generik?

10

Saat memprogram acara dalam C #, disarankan untuk membuat delegasi dalam bentuk:

delegate XEventHandler(object sender, XEventArgs e);

Pertanyaan saya ada pada argumen pertama delegasi object sender,. Apakah harus selalu menjadi generik object? Memiliki pengirim tipe objectselalu menghasilkan kode yang mirip dengan ini.

val = ((ConcreteType)sender).Property;

atau, bahkan lebih verbose,

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

Salah satu argumen yang menentang pengirim yang diketik dengan sangat adalah bahwa objek lain dapat meneruskan acara tanpa khawatir tentang jenisnya. Meskipun ini mungkin masuk akal di lingkungan GUI, saya tidak yakin apakah itu bisa menguntungkan di luar GUI.

Bagaimana jika kelas pengirim selalu dikenal (setidaknya sebagai kelas abstrak)? Misalnya, jika saya mengimplementasikan suatu ListChangedacara dalam Listkelas abstrak , dan jika kelas lain akan mewarisinya (misalnya LinkedList, ArrayList), apakah boleh mendefinisikan delegasi saya dengan pengirim tipe List?

delegate ListChangedEventHander(List sender, ListChangedEventArgs e);

Atau, akankah ada kerugian dari mengubah yang konvensional object senderke jenis yang lebih spesifik?

sampathsris
sumber

Jawaban:

10

Pada titik ini, sebagian besar merupakan konvensi (cukup kuat). Artinya, akan aneh jika Anda menulis perpustakaan yang tidak mengikuti konvensi itu.

The Pedoman Desain Acara mengatakan:

LAKUKAN gunakan objectsebagai jenis parameter pertama pengendali acara, dan panggil saja sender.

Namun, Anda dapat mencatat bahwa panduan saat ini mengatakan bahwa Anda tidak boleh menentukan delegasi khusus Anda untuk acara, tetapi gunakan EventHandler<T>sebaliknya, jika Anda bisa.

Sedangkan untuk desain, saya kira itu juga mempromosikan penggunaan kembali penangan acara, bahkan dalam konteks yang pada awalnya tidak diramalkan oleh perancang asli acara tersebut.

jhominal
sumber
2
Ughhh ... hanya karena Microsoft memutuskan untuk membuat pedoman mereka cukup generik untuk dapat diterapkan pada semua orang, tidak berarti itu adalah ide yang baik untuk semua orang untuk mengikuti pedoman mereka. Sangat mungkin bahwa "orang lain" tidak menulis kode untuk digunakan oleh jutaan pengembang lain. Saya merasa ngeri pada sekitar 2/3 dari rekomendasi dari tautan yang Anda berikan.
Dunk
Sejujurnya, "pedoman" ini kurang lebih terasa seperti notasi Hungaria Windows API. Seseorang yang brilian memulainya karena alasan yang sangat bagus dan kemudian semua orang mulai menyalahgunakannya. Ketika ada pedoman, lebih baik ada alasan bagus di balik pedoman itu. Dan apa yang saya pikirkan alasan untuk pedoman ini adalah bahwa System.Windows.Formsnamespace adalah tempat di mana peristiwa paling banyak digunakan, dan masuk akal untuk berlangganan Clickacara Buttonatau a CheckBox. Dengan demikian pengirim perlu menjadi generik. ...
sampathsris
... Tapi ketika datang ke area fungsionalitas lain yang lebih spesifik dan terkandung, pengirim mungkin tidak perlu menjadi kelas umum. Lihat lagi contoh saya tentang hierarki kelas Lists.
sampathsris
11
@Dunk: Dan itu intinya. Pedoman ini berasal dari Kerangka Desain Pedoman, yang terutama berkaitan dengan kode yang dikonsumsi oleh orang lain . Bukan karena itu solusi terbaik, tetapi karena itu paling tidak mengejutkan. Itu pilihan terbaik untuk suatu framework . Untuk perpustakaan yang lebih kecil, jika use-case ditentukan dengan baik, pedoman yang berlaku kurang. Microsoft secara eksplisit mengatakannya di awal buku.
Magus
1
Saya tidak berdebat dengan jawabannya, saya bahkan mengangkatnya karena itu berasal dari sumber yang memiliki reputasi baik. Saya hanya mengatakan bahwa saya tidak akan menggunakan pedoman. Jika suatu acara seharusnya mengirim data tertentu maka saya hanya akan mengirim data tertentu. Juga, fitur acara berfungsi dengan baik jika Anda menggunakannya bagaimana mereka dimaksudkan untuk digunakan.
Dunk
0

Alasan untuk rekomendasi ini adalah memungkinkan untuk perubahan di masa depan yang tidak memerlukan perubahan pada kode yang ada, dan terutama antarmuka publik.

Mekanisme acara itu sendiri masih dapat digunakan untuk acara-acara "VB6", tetapi Anda harus mengubah semua konsumen yang ada jika Anda perlu mengubah tanda tangan (atau lebih buruk: membuat versi baru dari acara yang sama). Dengan pendekatan yang disarankan, selama item baru mewarisi dari yang sudah ada, Anda dapat memperbarui tanda tangan tanpa memperbaiki kode yang ada.

Mark Hurd
sumber