Saya tidak melihat keuntungan menggunakan acara dibandingkan delegasi, selain menjadi gula sintaksis. Mungkin saya salah paham, tapi sepertinya acara itu hanya placeholder untuk delegasi.
Maukah Anda menjelaskan kepada saya perbedaannya dan kapan harus menggunakan yang mana? Apa kelebihan dan kekurangannya? Kode kami berakar kuat dengan peristiwa, dan saya ingin membukanya.
Kapan Anda akan menggunakan delegasi untuk acara dan sebaliknya? Sebutkan pengalaman dunia nyata Anda dengan keduanya, misalnya di kode produksi.
Jawaban:
Dari sudut pandang teknis, jawaban lain telah menjawab perbedaan tersebut.
Dari perspektif semantik, peristiwa adalah tindakan yang dimunculkan oleh suatu objek ketika kondisi tertentu terpenuhi. Misalnya, kelas Saham saya memiliki properti yang disebut Limit, dan itu menimbulkan peristiwa ketika harga saham mencapai Limit. Notifikasi ini dilakukan melalui sebuah acara. Apakah ada orang yang benar-benar peduli tentang acara ini dan berlangganan ke dalamnya, itu bukan urusan kelas pemilik.
Delegasi adalah istilah yang lebih umum untuk menggambarkan konstruksi yang mirip dengan pointer dalam istilah C / C ++. Semua delegasi di .Net adalah delegasi multicast. Dari perspektif semantik, umumnya digunakan sebagai semacam masukan. Secara khusus, ini adalah cara sempurna untuk menerapkan Pola Strategi . Sebagai contoh, jika saya ingin mengurutkan daftar objek, saya dapat memberikan strategi pembanding untuk metode untuk memberitahu implementasi bagaimana membandingkan dua objek.
Saya telah menggunakan dua metode dalam kode produksi. Banyak objek data saya memberi tahu saat properti tertentu terpenuhi. Contoh paling dasar, setiap kali properti berubah, acara PropertyChanged dimunculkan (lihat antarmuka INotifyPropertyChanged). Saya telah menggunakan delegasi dalam kode untuk memberikan strategi berbeda untuk mengubah objek tertentu menjadi string. Contoh khusus ini adalah daftar implementasi ToString () yang dimuliakan untuk tipe objek tertentu untuk ditampilkan kepada pengguna.
sumber
Kata kunci
event
adalah pengubah cakupan untuk delegasi multicast. Perbedaan praktis antara ini dan hanya mendeklarasikan delegasi multicast adalah sebagai berikut:event
di antarmuka.public event
).Sesuai minat, Anda dapat menerapkan
+
dan-
ke delegasi multicast, dan ini adalah dasar sintaks+=
dan-=
untuk penugasan kombinasi delegasi ke acara. Ketiga cuplikan ini setara:Contoh dua, menggambarkan penugasan langsung dan penugasan kombinasi.
Contoh tiga: sintaks yang lebih familiar. Anda mungkin terbiasa dengan tugas null untuk menghapus semua penangan.
Seperti properti, peristiwa memiliki sintaks lengkap yang tidak pernah digunakan siapa pun. Ini:
... melakukan hal yang sama persis seperti ini:
Metode tambah dan hapus lebih mencolok dalam sintaks yang agak kaku yang digunakan VB.NET (tidak ada operator yang kelebihan beban).
sumber
Acara adalah gula sintaksis. Mereka enak. Ketika saya melihat sebuah acara, saya tahu apa yang harus saya lakukan. Ketika saya melihat seorang delegasi, saya tidak begitu yakin.
Menggabungkan acara dengan antarmuka (lebih banyak gula) membuat camilan yang menggugah selera. Delegasi dan kelas abstrak virtual murni kurang menarik.
sumber
Peristiwa ditandai seperti itu di metadata. Hal ini memungkinkan hal-hal seperti desainer Windows Forms atau ASP.NET untuk membedakan kejadian dari properti tipe delegasi, dan memberikan dukungan yang sesuai untuk mereka (secara khusus menunjukkannya pada tab Kejadian pada jendela Properti).
Perbedaan lain dari properti tipe delegasi adalah bahwa pengguna hanya bisa menambah dan menghapus pengendali event, sedangkan dengan properti tipe delegasi mereka bisa menyetel nilainya:
Ini membantu memisahkan pelanggan acara: Saya dapat menambahkan penangan saya ke acara, dan Anda dapat menambahkan penangan ke acara yang sama, dan Anda tidak akan menimpa penangan saya secara tidak sengaja.
sumber
Meskipun acara biasanya diimplementasikan dengan delegasi multicast, tidak ada persyaratan bahwa acara tersebut digunakan dengan cara seperti itu. Jika kelas mengekspos acara, itu berarti kelas tersebut mengekspos dua metode. Artinya, pada dasarnya:
Cara paling umum bagi kelas untuk menangani peristiwa yang dipaparkannya adalah dengan mendefinisikan delegasi multicast, dan menambahkan / menghapus setiap delegasi yang diteruskan ke metode di atas tetapi tidak ada persyaratan bahwa mereka bekerja seperti itu. Sayangnya, arsitektur acara gagal melakukan beberapa hal yang akan membuat pendekatan alternatif jauh lebih bersih (misalnya, meminta metode berlangganan mengembalikan MethodInvoker, yang akan disimpan oleh pelanggan; untuk berhenti berlangganan acara, cukup panggil metode yang dikembalikan) sehingga delegasi multicast sejauh ini merupakan pendekatan yang paling umum.
sumber
untuk memahami perbedaannya Anda dapat melihat 2 contoh ini
Contoh dengan Delegasi (Tindakan dalam hal ini adalah jenis delegasi yang tidak mengembalikan nilai)
untuk menggunakan delegasi, Anda harus melakukan sesuatu seperti ini
kode ini berfungsi dengan baik tetapi Anda mungkin memiliki beberapa titik lemah.
Misalnya jika saya menulis ini
dengan baris kode terakhir yang saya timpa perilaku sebelumnya hanya dengan satu yang hilang
+
(saya gunakan+
sebagai gantinya+=
)Titik lemah lainnya adalah bahwa setiap kelas yang menggunakan
Animal
kelas Anda dapat menaikkanRaiseEvent
panggilannya sajaanimal.RaiseEvent()
.Untuk menghindari titik lemah ini Anda dapat menggunakan
events
di c #.Kelas Hewan Anda akan berubah dengan cara ini
untuk memanggil acara
Perbedaan:
catatan
EventHandler dideklarasikan sebagai delegasi berikut:
itu membutuhkan pengirim (tipe Object) dan argumen event. Pengirim bernilai null jika berasal dari metode statis.
Anda juga dapat menggunakan
EventHAndler
contoh yang menggunakan iniEventHandler<ArgsSpecial>
lihat di sini untuk dokumentasi tentang EventHandler
sumber
Ketika saya mendesain API saya sendiri, saya mendefinisikan delegasi yang diteruskan sebagai parameter ke metode, atau ke konstruktor kelas:
Predicate
danAction
diteruskan ke kelas koleksi generik .Net)Ini delegasi umumnya non-opsional pada saat run-time (yaitu tidak harus
null
).Saya cenderung tidak menggunakan acara; tetapi di mana saya menggunakan peristiwa, saya menggunakannya untuk secara opsional memberi sinyal peristiwa ke nol, satu, atau lebih klien yang mungkin tertarik, yaitu ketika masuk akal bahwa kelas (misalnya
System.Windows.Form
kelas) harus ada dan dijalankan apakah ada klien atau tidak menambahkan event handler ke eventnya (misal event form 'mouse down' ada, tapi opsional apakah ada klien eksternal yang tertarik untuk menginstal event handler ke event itu).sumber
Meskipun saya tidak punya alasan teknis untuk itu, saya menggunakan kejadian dalam kode gaya UI, dengan kata lain, di tingkat kode yang lebih tinggi, dan menggunakan delegasi untuk logika yang terletak lebih dalam di kode. Seperti yang saya katakan Anda dapat menggunakan keduanya, tetapi saya menemukan pola penggunaan ini terdengar logis, jika tidak ada yang lain, ini membantu mendokumentasikan jenis callback dan hierarki mereka juga.
Sunting: Saya pikir perbedaan dalam pola penggunaan yang saya miliki adalah bahwa, saya merasa sangat dapat diterima untuk mengabaikan acara, mereka adalah kait / rintisan, jika Anda perlu tahu tentang acara tersebut, dengarkan mereka, jika Anda tidak peduli acara tersebut abaikan saja. Itu sebabnya saya menggunakannya untuk UI, jenis gaya acara Javascript / Browser. Namun ketika saya memiliki delegasi, saya berharap BENAR-BENAR mengharapkan seseorang untuk menangani tugas delegasi, dan memberikan pengecualian jika tidak ditangani.
sumber
Perbedaan antara acara dan delegasi jauh lebih kecil daripada yang saya kira. Saya baru saja memposting video YouTube yang sangat pendek tentang subjek: https://www.youtube.com/watch?v=el-kKK-7SBU
Semoga ini membantu!
sumber
sumber