C#中ref和out的區別
C#中ref和out的區別
ref和out這兩個關鍵字都能夠提供相似的功效,其作用也很像C中的指標變數。它們的區別是:
1、使用ref型引數時,傳入的引數必須先被初始化。對out而言,必須在方法中對其完成初始化。
如:
static void Main(string[] args)
{
int a = 5;
int b =10;
squareRef(ref a);
squareOut(out b);
Console.WriteLine("The a in the Main is: " + a);
Console.WriteLine("The b in the Main is: " + b);
}
static void squareRef(ref int x)
{
x = x * x; //x的值引用是a中的值
Console.WriteLine("The x in the squareRef is: " + x);
}
static void squareOut(out int y)
{
y = 10; //此句不可刪,因為是out型賦值,y的改變同時影響到此函式外的b
y = y * y;
Console.WriteLine("The y in the squareOut is: " + y);
}
2、使用ref和out時,在方法的引數和執行方法時,都要加Ref或Out關鍵字。以滿足匹配。
3、out適合用在需要返回多個值(注:不是“多個返回值”)的地方,而ref則用在需要被呼叫的方法修改呼叫者的引用的時候。
static void testOut(out int a, out int b, out string c, out bool d)
{
a = 1;
b = 2;
c = "我是第三個引數";
d = true;
}
public static void Main()
{
int a, b;
string c;
bool d;
testOut(out a, out b, out c, out d);
//經過執行方法testOut(),相當於返回了a,b,c,d四個引數,也就是說out適合用於返回多個引數的情況
Console.Write("{0},{1},{2},{3}", a, b, c, d.ToString());
Console.Read();
}
注:在C#中,方法的引數傳遞有四種型別:傳值(by value),傳址(by reference),輸出引數(by output),陣列引數(by array)。傳值引數無需額外的修飾符,傳址引數需要修飾符ref,輸出引數需要修飾符out,陣列引數需要修飾符params。傳值引數在方法呼叫過程中如果改變了引數的值,那麼傳入方法的引數在方法呼叫完成以後並不因此而改變,而是保留原來傳入時的值。傳址引數恰恰相反,如果方法呼叫過程改變了引數的值,那麼傳入方法的引數在呼叫完成以後也隨之改變。實際上從名稱上我們可以清楚地看出兩者的含義--傳值引數傳遞的是呼叫引數的一份拷貝,而傳址引數傳遞的是呼叫引數的記憶體地址,該引數在方法內外指向的是同一個儲存位置。
方法引數上的 ref 方法引數關鍵字使方法引用傳遞到方法的同一個變數。當控制傳遞迴呼叫方法時,在方法中對引數所做的任何更改都將反映在該變數中。
若要使用 ref 引數,必須將引數作為 ref 引數顯式傳遞到方法。ref 引數的值被傳遞到 ref 引數。
傳遞到 ref 引數的引數必須最先初始化。將此方法與 out 引數相比,後者的引數在傳遞到 out 引數之前不必顯式初始化。
屬性不是變數,不能作為 ref 引數傳遞。
如果兩種方法的宣告僅在它們對 ref 的使用方面不同,則將出現過載。但是,無法定義僅在 ref 和 out 方面不同的過載。
out
方法引數上的 out 方法引數關鍵字使方法引用傳遞到方法的同一個變數。當控制傳遞迴呼叫方法時,在方法中對引數所做的任何更改都將反映在該變數中。
當希望方法返回多個值時,宣告 out 方法非常有用。使用 out 引數的方法仍然可以返回一個值。一個方法可以有一個以上的 out 引數。
若要使用 out 引數,必須將引數作為 out 引數顯式傳遞到方法。out 引數的值不會傳遞到 out 引數。
不必初始化作為 out 引數傳遞的變數。然而,必須在方法返回之前為 out 引數賦值。
屬性不是變數,不能作為 out 引數傳遞。
網上有很多文章說ref 只傳值,out傳地址等等這種說法,好像不是非常的準確。以下是我做的例項程式碼,大家可以去試試:
public int RefValue(int i,ref int j)
{
int k = j;
j =222;
return i+k;
}
public int OutValue(int i, out int j)
{
j = 222;
return i + j;
}
private void cmdRef_Click(object sender, EventArgs e)
{
int m = 0;
MessageBox.Show(RefValue(1, ref m).ToString());
MessageBox.Show(m.ToString());
}
private void cmdOut_Click(object sender, EventArgs e)
{
int m;
MessageBox.Show(OutValue(1, out m).ToString());
MessageBox.Show(m.ToString());
}
相關文章
- out關鍵字和ref關鍵字的區別
- Rust 中 *、&、mut、&mut、ref、ref mut 的用法和區別Rust
- c#基礎系列3—深入理解ref 和outC#
- Spring中ref local=""與ref bean=""的區別SpringBean
- Vue 中ref()與 reactive() 的區別VueReact
- C#中Hashtable和HashMap的區別C#HashMap
- [C#]C#中ToString()和Convert.ToString()的區別C#
- c#中Debug和Release的區別實驗C#
- C# 中 Struct 和 Class 的區別總結C#Struct
- Lua中呼叫ref和out修飾引數的函式/過載函式函式
- 簡單介紹Tomcat中catalina.out 和 catalina.log的區別和用途Tomcat
- out,ref,params引數傳遞
- C# 中List中的Count和Count(),有什麼區別C#
- 淺談C#中重寫和隱藏的區別C#
- c#中值型別和引用型別的區別C#型別
- vue中的 ref 和 $refsVue
- Tomcat 中 catalina.out、catalina.log、localhost.log 和 access_log 的區別Tomcatlocalhost
- C# ToString()和Convert.ToString()的區別C#
- 認真總結Vue3中ref與reactive區別和isRef與isReactive 型別判斷VueReact型別
- Python和C#有哪些區別?PythonC#
- c# 方法引數(傳值,傳引用,ref,out,params,可選引數,命名引數)C#
- JavaScript中==和===的區別JavaScript
- Linux中“>”和“>>”的區別Linux
- Python 中 is 和 == 的區別Python
- Python中is和==的區別Python
- mysql中“ ‘ “和 “ ` “的區別MySql
- JavaScript中for in 和for of的區別JavaScript
- Js中for in 和for of的區別JS
- mysql中!=和is not的區別MySql
- 徹底弄懂C#中delegate、event、EventHandler、Action、Func的使用和區別C#
- Kotlin 泛型中的 in 和 outKotlin泛型
- C#中continue、return、break的區別及作用C#
- PHP 中的 -> 和 :: 的區別PHP
- SQL中where和on的區別SQL
- java 中equals和==的區別Java
- deferred中done和then的區別
- .net與C#的區別C#
- JS中的!=、== 、!==、=== 的用法和區別JS
- 棧(Stack) --- C# 自定義和微軟官方的區別C#微軟