想問一下大佬們,ref和out是把值型別轉化為引用型別了嗎?按理來說值型別就是值型別,怎麼會轉為引用型別?能不能詳細講解一下!感謝!!!
封箱、拆箱
引數是什麼型別還是什麼型別,不會改變的
引用型別不用ref或out,都是在堆上,改變了資料就會影響原來的
而值型別不用的話就會重新分配乙個位址,用上了就用原來的位址
不要太深究。
object是萬物的基類。
值型別和引用型別都派生自object。
而object自己是引用型別。
你說,那引用型別,怎麼就生出乙個值型別的小孩了呢?
對對,我繞進去了,可以通過裝箱和拆箱操作進行轉化,不過ref和out好像並沒有進行裝箱操作
大哥,我也不想深究,面試問這個啊
根據大佬們的解釋以及我又查了資料,我重新理解為這樣的:值型別其實也包含位址和值,不過看上去都是自身,平時變數間傳遞是值的傳遞,用ref/out修飾形參後傳遞給形參的是位址,c#在底層**應該會判斷各種情況並加以標識。我只能這樣理解了
ref/out引用傳遞本身沒有用到"封箱、拆箱"。
ref/out的dotnet的實現無非就是傳遞乙個『記憶體位址』。
比如有乙個結構my
struct my
執行後乙個my的例項1在記憶體裡的布局將類似(17821540等數字,是記憶體位址):
17821540:
--> 17821544:a
17821548:b
17821552:c
17821556:d
乙個int占用4個位元組的記憶體,可以看到,b跟在a的後面,c跟在b的後面,d跟在c的後面,記憶體偏移都是4個位元組。
如果我們把17821544傳給某個過程,而該過程修改了記憶體17821548下的內容,實際上就等於修改例項1的b的值。
我們可以理解成17821544就是例項1的『引用』,傳遞17821544的方式就是ref引用傳遞。
相形之下,按值傳遞則是拷貝了整個例項1的a,b,c,d的值,共4個int。按值傳遞後,過程對傳入引數的修改,將修改到乙個臨時的記憶體拷貝下,不會影響到原來的例項1。
以下的示例**需要設定專案屬性/編譯/允許unsafe:
unsafe
class
program
static
void
byref(
ref
my my)
}
static
void
byval(my my)
}
struct
my
}
我的機器的執行結果為:
[ main] address of my: 17821544
[ main] address of my.b: 17821548
[byref] address of my: 17821544
[byref] address of my.b: 17821548
[byval] address of my: 17821432
[byval] address of my.b: 17821436
可以看到,在【byref】過程中,除錯列印出的結構位址和【main】呼叫方中結構位址是一樣的,這就是按引用傳遞的實現。
可以看到,在【byval】過程中,除錯列印出的結構位址和【main】呼叫方中結構位址是不一樣,因為byval過程中得到的是乙個臨時拷貝。
注:這裡可以理解成17821544就是例項1的『引用』。但嚴格意義上它不是dotnet所謂的引用.
乙個int占用4個位元組的記憶體,可以看到,b跟在a的後面,c跟在b的後面,d跟在c的後面,記憶體偏移都是4個位元組。
如果我們把17821544傳給某個過程,而該過程修改了記憶體17821548下的內容,實際上就等於修改例項1的b的值。
我們可以理解成17821544就是例項1的『引用』,傳遞17821544的方式就是ref引用傳遞。
相形之下,按值傳遞則是拷貝了整個例項1的a,b,c,d的值,共4個int。按值傳遞後,過程對傳入引數的修改,將修改到乙個臨時的記憶體拷貝下,不會影響到原來的例項1。
這也太本質了吧,贊!!
ref和out的原理及區別
一 建立ref引數 在使用引數時,將引數傳遞給方法使用,而方法中對此值的任何改變並不能影響方法外部的變數。下面乙個例子,控制台輸出4,並沒有對變數進行增量。例如 class reforout public static void main string args i console.readline...
C 中ref和out的原理
去年在csdn 上寫的,現在把它搬過來。用了那麼久的ref和out,你真的了解它們是如何使得實參與形參的值保持同步的嗎?要研究這個問題,前提是要了解c 中方法間引數是如何傳遞的 1.clr支援兩種型別 值型別和引用型別。表示引用型別 2class ref312 13 1415 static void...
使用ref和out引數
ref型別引數側重修改,out型別引數側重輸出 ref在傳入值之前必須先初始化 out在函式內,函式結束之前,即傳出值之前初始化.eg protected void page load object sender,eventargs e int indexref 1 testref ref inde...