Saya mencoba melakukan kelebihan beban operator +=
, tetapi saya tidak bisa. Saya hanya bisa membuat operator kelebihan beban +
.
Bagaimana bisa?
Sunting
Alasan ini tidak berhasil adalah karena saya memiliki kelas Vektor (dengan bidang X dan Y). Perhatikan contoh berikut.
vector1 += vector2;
Jika kelebihan beban operator saya disetel ke:
public static Vector operator +(Vector left, Vector right)
{
return new Vector(right.x + left.x, right.y + left.y);
}
Maka hasilnya tidak akan ditambahkan ke vektor1, tetapi sebagai gantinya, vektor1 akan menjadi Vektor baru dengan referensi juga.
Jawaban:
Operator Overloadable , dari MSDN:
Terlebih lagi, tidak ada operator penugasan yang dapat kelebihan beban. Saya pikir ini karena akan ada efek untuk pengumpulan Sampah dan manajemen memori, yang merupakan lubang keamanan potensial di dunia tipe CLR yang kuat.
Namun demikian, mari kita lihat apa sebenarnya operator itu. Menurut buku Jeffrey Richter yang terkenal , setiap bahasa pemrograman memiliki daftar operatornya sendiri, yang disusun dalam metode panggilan khusus, dan CLR sendiri tidak tahu apa-apa tentang operator. Jadi mari kita lihat apa sebenarnya yang tertinggal di belakang operator
+
dan+=
.Lihat kode sederhana ini:
Mari lihat kode IL untuk instruksi ini:
Sekarang mari kita lihat kode ini:
Dan kode IL untuk ini:
Mereka sama! Jadi
+=
operator hanyalah gula sintaksis untuk program Anda di C # , dan Anda cukup membebani+
operator.Sebagai contoh:
Kode ini akan dikompilasi dan berhasil dijalankan sebagai:
Memperbarui:
Menurut Pembaruan Anda - seperti yang dikatakan @EricLippert, Anda benar-benar harus memiliki vektor sebagai objek yang tidak dapat diubah. Hasil penjumlahan kedua vektor tersebut adalah vektor baru , bukan vektor pertama dengan ukuran berbeda.
Jika, karena alasan tertentu Anda perlu mengubah vektor pertama, Anda dapat menggunakan kelebihan ini (tetapi bagi saya, ini adalah perilaku yang sangat aneh):
sumber
v3 = v1 + v2;
hasil pernyataanv1
berubah danv3
tidak biasaSaya pikir Anda akan menemukan tautan ini informatif: Operator Overloadable
sumber
Ini karena alasan yang sama bahwa operator penugasan tidak dapat kelebihan beban. Anda tidak dapat menulis kode yang akan melakukan tugas dengan benar.
Dari MSDN .
sumber
Anda tidak dapat membebani berlebihan
+=
karena ini bukan operator unik, itu hanya gula sintaksis .x += y
hanyalah cara penulisan singkatx = x + y
. Karena+=
didefinisikan dalam istilah operator+
dan=
, memungkinkan Anda untuk menimpanya secara terpisah dapat menimbulkan masalah, dalam kasus di manax += y
danx = x + y
tidak berperilaku dengan cara yang persis sama.Pada level yang lebih rendah, sangat mungkin bahwa compiler C # mengkompilasi kedua ekspresi tersebut ke bytecode yang sama, yang berarti bahwa sangat mungkin runtime tidak dapat memperlakukannya secara berbeda selama eksekusi program.
Saya dapat memahami bahwa Anda mungkin ingin memperlakukannya seperti operasi terpisah: dalam pernyataan seperti
x += 10
Anda tahu bahwa Anda dapat mengubahx
objek di tempat dan mungkin menghemat waktu / memori, daripada membuat objek barux + 10
sebelum menetapkannya di atas referensi lama .Tetapi pertimbangkan kode ini:
Haruskah
a == b
di akhir? Untuk kebanyakan tipe, tidak,a
lebih dari 10b
. Tetapi jika Anda bisa membebani+=
operator untuk bermutasi di tempat, maka ya. Sekarang pertimbangkan itua
danb
dapat disebarkan ke bagian program yang jauh. Pengoptimalan yang mungkin Anda lakukan dapat membuat bug yang membingungkan jika objek Anda mulai berubah di tempat yang tidak diharapkan oleh kode.Dengan kata lain, jika kinerja itu penting, tidak terlalu sulit untuk mengganti
x += 10
dengan pemanggilan metode sepertix.increaseBy(10)
, dan itu jauh lebih jelas bagi semua orang yang terlibat.sumber
it's just syntactic sugar
menjadiit's just syntactic sugar in C#
; jika tidak, kedengarannya terlalu umum, tetapi dalam beberapa bahasa pemrograman, ini bukan hanya gula sintaksis tetapi mungkin benar-benar memberikan manfaat kinerja.+=
Mungkin dapat dioptimalkan oleh kompiler cerdas, karena aritmatika itu sederhana. Tapi begitu Anda berurusan dengan objek, semua taruhan dibatalkan. Bahasa apa pun menghadapi masalah yang hampir sama. Inilah sebabnya mengapa kelebihan beban operator itu jahat.Ini karena operator ini tidak bisa kelebihan beban:
MSDN
Hanya membebani
+
operator, karenax += y
sama denganx = x + y
sumber
Operator overload untuk
+
digunakan di+=
operator,A += B
sama denganA = operator+(A, B)
.sumber
Jika Anda membebani
+
operator seperti ini:Anda dapat melakukan
atau
Ini akan mengkompilasi dan berjalan sama.
sumber
Selalu ada jawaban yang sama untuk masalah ini: Mengapa Anda membutuhkan
+=
, jika Anda mendapatkannya secara gratis jika Anda membebani file+
. Tapi apa jadinya kalau saya punya kelas seperti ini.Apakah Anda masih mengatakan bahwa itu bagus karena
+=
"diterapkan secara otomatis". Jika Anda mencoba melakukan komputasi berkinerja tinggi di C #, Anda perlu memiliki fitur seperti itu untuk mengurangi waktu pemrosesan dan konsumsi memori, jika seseorang memiliki solusi yang baik, itu sangat dihargai, tetapi jangan beri tahu saya bahwa saya harus melakukan ini dengan metode statis , ini hanya solusi dan saya tidak melihat alasan mengapa C # melakukan+=
implementasi jika tidak ditentukan, dan jika sudah ditentukan maka akan digunakan. Beberapa orang mengatakan bahwa tidak memiliki perbedaan antara+
dan+=
mencegah kesalahan, tetapi bukankah ini masalah saya sendiri?sumber
+=
adalah masalah Anda sendiri ... itu hanya benar jika tidak ada orang lain yang harus membaca, memelihara, atau mengeksekusi kode Anda.List<T>
menggunakan operator sepertilist += "new item"
, misalnya. Anda menyebutAdd
metodenya sebagai gantinya.Saya memiliki pertanyaan yang persis sama dan saya tidak mungkin menjawabnya dengan lebih baik daripada orang ini
sumber
Metode desain yang lebih baik adalah Pengecoran Eksplisit. Anda pasti dapat membebani Casting.
sumber