首先:兩者都是按位址傳遞的,使用後都將改變原來引數的數值。其次:ref可以把引數的數值傳遞進函式,但是out是要把引數清空,就是說你無法把乙個數值從out傳遞進去的,out進去後,引數的數值為空,所以你必須初始化一次。這個就是兩個的區別,或者說就像有的網友說的,ref是有進有出,out是只出不進。
需求假設:現需要通過乙個叫swap的方法交換a,b兩個變數的值。交換前a=1,b=2,斷言:交換後a=2,b=1
。現編碼如下:
class
program
\tb=\t
",a,b);
swap(a,b);
console.writeline(
"交換後\ta=\tb=\t
",a,b);
console.read();
}//交換a,b兩個變數的值
private
static
void swap(int a,int
b) \tb=\t
",a,b);}}
執行結果:
交換前 a = 1 b = 2
方法內 a = 2 b = 1
交換後 a = 1 b = 2
斷言失敗,並未達到我們的需求!原因分析:int型別為值型別,它存在於執行緒的堆疊中。當呼叫swap(a,b)方法時,相當於把a,b的值(即1,
2)拷貝乙份,然後在方法內交換這兩個值。交換完後,a還是原來的a,b還是原來的b。這就是c#中按值傳遞的原理,傳遞的是變數所對應資料的乙個拷貝,而非引用。
解決方案:因此,c#中提出了ref 和out兩個關鍵字。
修改**如下即可實現我們想要的結果:
class
program
\tb=\t
",a,b);
swap(
ref a,ref
b); console.writeline(
"交換後\ta=\tb=\t
",a,b);
console.read();
}//交換a,b兩個變數的值
private
static
void swap(ref
int a, ref
intb)
\tb=\t
",a,b);}}
同理用out同樣可以實現我們的需求。
下面談談ref和out到底有什麼區別:
1關於過載
ref 和 out 關鍵字在執行時的處理方式不同,但在編譯時的處理方式相同。因此,如果乙個方法採用 ref 引數,而另乙個方法採用 out
引數,則無法過載這兩個方法。例如,從編譯的角度來看,以下**中的兩個方法是完全相同的,因此將不會編譯以下**:
class
cs0663_example
public
void samplemethod(ref
inti) }
但是,如果乙個方法採用
ref 或 out
引數,而另乙個方法不採用這兩類引數,則可以進行過載,如下所示:
class
refoutoverloadexample
public
void samplemethod(out
inti) }2
關於呼叫前初始值
out作為引數的函式在呼叫前,實參可以不賦初始值。
3關於在函式內,引入的引數初始值問題
在被呼叫函式內,ref引入的引數在返回前不必為其賦初值。
c ref 和 out 的區別
乙個用關鍵字 ref 標示,乙個用 out 標示。牽扯到資料是引用型別還是值型別。一般用這兩個關鍵字你是想呼叫乙個函式將某個值型別的資料通過乙個函式後進行更改。傳 out 定義的引數進去的時候這個引數在函式內部必須初始化。否則是不能進行編譯的。ref 和 out 都是傳遞資料的位址,正因為傳了位址,...
c ref與out的區別
c ref與out的區別 相同點 都是輸出引數 不同點 ref 1 必須初始化,即 必須賦初始值 2.有進有出 3 用在需要被呼叫的方法修改呼叫者的引用的時候。4 是傳遞引數的位址 out 1.不需要初始化,即 不需要賦初始值 2 只出不進 3 用在需要retrun多個返回值的地方 4 返回值 通過...
C Ref 與out 的區別
在c 中,有四種傳遞引數方式 1.傳值 value 無額外修飾符 2.傳址 reference 需修飾符ref,傳入函式的引數必須先賦值 3.輸出引數 output 需修飾符out,適用於return多個返回值,必須在方法中賦值 4.陣列引數 array 需修飾符params 而out是只出不進 外...