C # menyediakan ref
dan out
kata kunci untuk membuat argumen untuk dilewatkan dengan referensi. Semantik keduanya sangat mirip. Satu-satunya perbedaan adalah dalam inisialisasi dari variabel yang digerakkan:
ref
membutuhkan variabel yang diinisialisasi sebelum meneruskannya ke fungsi,out
tidak.out
membutuhkan variabel yang diinisialisasi di dalam fungsi,ref
tidak.
Kasus penggunaan kedua kata kunci ini juga hampir sama, dan penggunaannya yang terlalu sering saya percaya dianggap sebagai bau kode (meskipun ada kasus penggunaan yang valid seperti TryParse
dan TryGetValue
pola).
Karena ini dapatkah seseorang menjelaskan, mengapa ada dua alat yang sangat mirip dalam C # untuk kasus penggunaan yang begitu sempit?
Juga, pada MSDN , dinyatakan bahwa mereka memiliki perilaku run-time yang berbeda:
Meskipun kata kunci ref dan out menyebabkan perilaku run-time yang berbeda, mereka tidak dianggap sebagai bagian dari tanda tangan metode pada waktu kompilasi.
Bagaimana perilaku run-time mereka berbeda?
Kesimpulan
Kedua jawaban terlihat benar, terima kasih keduanya. Saya menerima jmoreno karena lebih eksplisit.
sumber
ref
di C ++; ke pointer ke penunjuk objek (atau primitif) yang dimaksud. yaituInt32.TryParse(myStr, out myInt)
(C #) "dieksekusi" dengan cara yang sama sepertiint32_tryParse(myStr, &myInt)
(C); satu-satunya perbedaan adalah beberapa kendala yang diberlakukan oleh kompiler untuk mencegah bug. (Saya tidak akan memposting ini sebagai jawaban karena saya mungkin salah tentang bagaimana ini bekerja di belakang layar, tetapi ini adalah bagaimana saya membayangkan itu bekerja [karena masuk akal])Jawaban:
Pada saat pertanyaan ini ditanyakan, artikel MSDN agak salah ( sejak itu telah diperbaiki ). Alih-alih "menyebabkan perilaku yang berbeda" itu harus "memerlukan perilaku yang berbeda".
Khususnya, kompiler memberlakukan persyaratan yang berbeda untuk dua kata kunci, meskipun mekanisme yang sama (IL) digunakan untuk mengaktifkan perilaku tersebut.
sumber
out
parameter atau tidak menetapkanref
parameter, tetapi IL yang dipancarkannya hanyalah referensi. Apakah itu benar?out T
danref T
diterjemahkan secara identik dalam bahasa CLI lain seperti VB.Net atau C ++ / CLI.inilah artikel yang menarik tentang topik yang dapat menjawab pertanyaan Anda:
http://www.dotnetperls.com/ref
minat:
"Perbedaan antara ref dan out tidak dalam Common Language Runtime, tetapi dalam bahasa C # itu sendiri."
memperbarui:
pengembang senior di tempat kerja saya hanya menguatkan jawaban @ jmoreno, jadi pastikan Anda membacanya !.
sumber
string
hubungannya dengan semua ini?Runtime ? Sama sekali tidak ada. Anda tidak dapat membebani metode dengan parameter yang sama hanya berbeda dengan ref atau kata kunci.
Coba kompilasi ini dan Anda akan mendapatkan kesalahan kompilasi "Metode dengan tanda tangan yang sama sudah dinyatakan":
Untuk menjawab pertanyaan ini: "... mengapa ada dua alat yang sangat mirip dalam C # untuk kasus penggunaan yang begitu sempit?"
Dari keterbacaan kode dan sudut pandang API ada perbedaan besar. Sebagai konsumen API saya tahu bahwa ketika "keluar" digunakan, API tidak bergantung pada parameter keluar. Sebagai pengembang API saya lebih suka "keluar" dan menggunakan "ref" hanya ketika benar-benar (Jarang!) Diperlukan. Lihat referensi ini untuk diskusi yang hebat:
/programming/1516876/when-to-use-ref-vs-out
Info pendukung: Saya mengkompilasi metode berikut dan membongkarnya. Saya menggunakan kata kunci ref dan out (dalam contoh ini), tetapi kode assembly tidak berubah kecuali untuk referensi alamat seperti yang saya harapkan:
00000000 push ebp
00000001 mov ebp, esp
00000003 push edi
00000004 push esi
00000005 push ebx
00000006 sub esp, 34h
00000009 xor eax, eax
0000000b mov dword ptr [ebp-10h], eax
0000000e mov dword ptr [ebp-
0000] mov dword ptr [ebp-3Ch], ecx
00000014 mov dword ptr [ebp-40h], edx
00000017 cmp dword ptr ds: [008B1710h], 0
0000001e je 00000025
00000020 call 6E6B601E
00000025 nop
param = 0;
00000026 mov eax, dword ptr [ebp-40h]
00000029 xor edx, edx
0000002b mov dword ptr [eax], edx
}
0000002d nop
0000002e lea esp, [ebp-0Ch]
00000031 pop ebx
00000032 pop esi
00000033 pop edi
00000034 pop ebp
00000035 ret
Apakah saya membaca perakitan dengan benar?
sumber