Saya memiliki objek yang saya dalam status memori program dan juga memiliki beberapa fungsi pekerja lain yang saya berikan objek untuk mengubah status. Saya telah meneruskannya dengan ref ke fungsi pekerja. Namun saya menemukan fungsi berikut.
byte[] received_s = new byte[2048];
IPEndPoint tmpIpEndPoint = new IPEndPoint(IPAddress.Any, UdpPort_msg);
EndPoint remoteEP = (tmpIpEndPoint);
int sz = soUdp_msg.ReceiveFrom(received_s, ref remoteEP);
Ini membingungkan saya karena keduanya received_s
dan remoteEP
mengembalikan barang dari fungsi. Mengapa remoteEP
perlu ref
dan received_s
tidak?
Saya juga seorang programmer ac jadi saya mengalami masalah dalam mendapatkan petunjuk dari kepala saya.
Sunting: Sepertinya objek di C # adalah penunjuk ke objek di bawah tenda. Jadi, saat Anda meneruskan objek ke suatu fungsi, Anda kemudian dapat mengubah konten objek melalui penunjuk dan satu-satunya hal yang diteruskan ke fungsi tersebut adalah penunjuk ke objek sehingga objek itu sendiri tidak sedang disalin. Anda menggunakan ref atau keluar jika Anda ingin dapat beralih atau membuat objek baru dalam fungsi yang seperti penunjuk ganda.
if (int.TryParse(text, out int value)) { ... use value here ... }
Pikirkan parameter non-ref sebagai penunjuk, dan parameter ref sebagai penunjuk ganda. Ini paling membantu saya.
Anda hampir tidak boleh melewatkan nilai dengan ref. Saya menduga bahwa jika bukan karena masalah interop, tim .Net tidak akan pernah memasukkannya ke dalam spesifikasi aslinya. Cara OO untuk menangani sebagian besar masalah yang dipecahkan oleh parameter ref adalah dengan:
Untuk beberapa nilai pengembalian
Untuk primitif yang berubah dalam metode sebagai hasil dari pemanggilan metode (metode memiliki efek samping pada parameter primitif)
sumber
IPAddress.TryParse(string, out IPAddress)
.if (int.TryParse("123", out var theInt) { /* use theInt */ }
kita memilikinyavar candidate = int.TrialParse("123"); if (candidate.Parsed) { /* do something with candidate.Value */ }
Ini lebih banyak kode, tetapi jauh lebih konsisten dengan desain bahasa C #.Anda mungkin bisa menulis seluruh aplikasi C # dan tidak pernah melewatkan objek / struct oleh ref.
Saya memiliki seorang profesor yang memberi tahu saya ini:
Saya setuju dengan sarannya, dan dalam lima tahun lebih saya sejak sekolah, saya tidak pernah membutuhkannya selain memanggil Framework atau Windows API.
sumber
SetName(person, "John Doe")
, properti nama akan berubah dan perubahan itu akan tercermin ke pemanggil.Karena accept_s adalah larik, Anda meneruskan penunjuk ke larik itu. Fungsi memanipulasi data yang sudah ada di tempatnya, tidak mengubah lokasi atau penunjuk yang mendasarinya. Kata kunci ref menandakan bahwa Anda meneruskan penunjuk yang sebenarnya ke lokasi dan memperbarui penunjuk itu di fungsi luar, sehingga nilai di fungsi luar akan berubah.
Misalnya byte array adalah penunjuk ke memori yang sama sebelum dan sesudah, memori tersebut baru saja diperbarui.
Referensi Endpoint sebenarnya memperbarui penunjuk ke Endpoint di fungsi luar ke instance baru yang dihasilkan di dalam fungsi.
sumber
Pikirkan ref sebagai arti Anda melewati pointer dengan referensi. Tidak menggunakan ref berarti Anda melewatkan pointer dengan nilai.
Lebih baik lagi, abaikan apa yang baru saja saya katakan (mungkin menyesatkan, terutama dengan tipe nilai) dan baca halaman MSDN ini .
sumber
pemahaman saya adalah bahwa semua objek yang berasal dari kelas Object diteruskan sebagai pointer sedangkan tipe biasa (int, struct) tidak dilewatkan sebagai pointer dan memerlukan ref. Saya tidak yakin tentang string (apakah itu pada akhirnya berasal dari kelas Object?)
sumber
Sementara saya setuju dengan jawaban Jon Skeet secara keseluruhan dan beberapa jawaban lainnya, ada kasus penggunaan untuk digunakan
ref
, dan itu untuk memperketat pengoptimalan kinerja. Telah diamati selama pembuatan profil kinerja bahwa pengaturan nilai kembalian suatu metode memiliki sedikit implikasi kinerja, sedangkan menggunakanref
sebagai argumen di mana nilai kembalian diisi ke dalam parameter itu menghasilkan sedikit kemacetan yang dihilangkan.Ini benar-benar hanya berguna jika upaya pengoptimalan dilakukan ke tingkat ekstrem, mengorbankan keterbacaan dan mungkin kemampuan pengujian dan pemeliharaan untuk menghemat milidetik atau mungkin sepersekian milidetik.
sumber
Dasar nol aturan pertama, Primitif diteruskan oleh nilai (tumpukan) dan Non-Primitif dengan referensi (Heap) dalam konteks JENIS yang terlibat.
Parameter yang terlibat diteruskan oleh Nilai secara default. Pos bagus yang menjelaskan banyak hal secara detail. http://yoda.arachsys.com/csharp/parameters.html
Kita dapat mengatakan (dengan peringatan) Jenis non-primitif hanyalah Pointer Dan ketika kita melewatinya ref kita dapat mengatakan kita melewati Pointer Ganda
sumber