Saat menggunakan masalah myDelegate -= eventHandler
ReSharper (versi 6):
Pengurangan delegasi memiliki hasil yang tidak dapat diprediksi
Alasan di balik ini dijelaskan oleh JetBrains di sini . Penjelasannya masuk akal dan, setelah membacanya, saya meragukan semua kegunaan saya -
pada delegasi.
Lalu bagaimana ,
- dapatkah saya menulis acara non-otomatis tanpa membuat ReSharper marah?
- atau, apakah ada cara yang lebih baik dan / atau "benar" untuk menerapkan ini?
- atau, bisakah saya mengabaikan ReSharper?
Berikut kode yang disederhanakan:
public delegate void MyHandler (object sender);
MyHandler _myEvent;
public event MyHandler MyEvent
{
add
{
_myEvent += value;
DoSomethingElse();
}
remove
{
_myEvent -= value; // <-- ReSharper warning here
}
}
Jawaban:
Jangan takut! Bagian pertama dari peringatan ReSharper hanya berlaku untuk menghapus daftar delegasi. Dalam kode Anda, Anda selalu menghapus satu delegasi. Bagian kedua berbicara tentang pemesanan delegasi setelah delegasi duplikat dihapus. Peristiwa tidak menjamin urutan eksekusi untuk pelanggannya, sehingga tidak terlalu memengaruhi Anda.
ReSharper mengeluarkan peringatan ini karena pengurangan delegasi multicast dapat berakibat fatal, itu tidak mengutuk fitur bahasa itu sepenuhnya. Untungnya gotcha itu ada dalam kasus pinggiran dan Anda tidak mungkin menemukannya jika Anda hanya memperagakan acara sederhana. Tidak ada cara yang lebih baik untuk menerapkan
add
/remove
penangan Anda sendiri , Anda hanya perlu memperhatikan.Saya menyarankan untuk menurunkan tingkat peringatan ReSharper untuk pesan itu menjadi "Petunjuk" sehingga Anda tidak peka terhadap peringatan mereka, yang biasanya berguna.
sumber
Delegate
tidak tidak membebani+
dan-
.)PIT OF SUCCESS IS THAT WAY --->
.Delegate.Combine
yang "mendatar" delegasi multicast, jadi jika diberikan delegasi [X, Y] dan Z, tidak dapat membedakan apakah hasilnya harus [X, Y, Z] atau [[ X, Y], Z] (delegasi terakhir memegang[X,Y]
delegasi sebagai miliknyaTarget
, danInvoke
metode delegasi itu sebagai miliknyaMethod
).Anda tidak boleh secara langsung menggunakan delegasi untuk menjumlahkan atau mengurangi. Sebaliknya bidang Anda
Sebaliknya harus dinyatakan sebagai acara juga. Ini akan menyelesaikan masalah tanpa mempertaruhkan solusi Anda dan masih memiliki manfaat penggunaan acara.
Penggunaan jumlah atau pengurangan delegasi berbahaya karena Anda bisa kehilangan peristiwa ketika hanya menetapkan delegasi (sesuai deklarasi, pengembang tidak akan langsung menyimpulkan ini adalah delegasi Multicast seperti ketika dideklarasikan sebagai peristiwa). Sebagai contoh, jika properti yang disebutkan pada pertanyaan ini tidak ditandai sebagai peristiwa, kode di bawah ini akan membuat dua tugas pertama menjadi HILANG, karena seseorang hanya ditugaskan ke delegasi (yang juga valid!).
Saat menetapkan Method3, saya benar-benar kehilangan dua langganan awal. Penggunaan acara akan menghindari masalah ini dan pada saat yang sama menghapus peringatan ReSharper.
sumber
setel ke = null daripada menggunakan - =
sumber
remove
metode dari suatu peristiwa tidak harus menghapus semua penangan, melainkan handler yang diminta untuk dihapus.