1.以傳值方式傳遞實質型別
「傳值呼叫」是指當呼叫方法時,呼叫方法的實引數會複製一份給被呼叫方法的虛引數
所以實引數和虛引數佔用不同的記憶體位址。
當被呼叫方法內的參數的任何變更並不會影響到變數原本的值。
C#預設為傳值呼叫,可保護變數不被修改
可以想成如下的圖
例:
實質型別的變數n(值=5)。
在叫用SquareIt 時,
n 的內容便會複製到方法括號內的 x 參數。
發生在方法內的變更只會影響區域變數x。
class PassingValByVal { static void SquareIt(int x) { x *= x; System.Console.WriteLine("在方法內的變數值是: {0}", x); } static void Main() { int n = 5; System.Console.WriteLine("呼叫方法前的變數值是: {0}", n); SquareIt(n); System.Console.WriteLine("呼叫方法後的變數值是: {0}", n); } } /* Output: 呼叫方法前的變數值是: 5 在方法內的變數值是: 25 呼叫方法後的變數值是: 5 */
2.以傳址方式傳遞實質型別
有時候會碰到這樣的需求,提供給某方法的引數會希望輸出處理過的結果並回存到原本的變數上
此時就得用傳址參數 -- ref 或 out 參數來完成,兩者極為相似但有些許不同和需要注意的地方,
以下摘錄自 MSDN Library:
以 ref 參數傳遞的引數必須先被初始化,out 則不需要。
out 參數要在離開目前的方法之前至少有一次指派值的動作。
若兩個方法僅有 ref、out 關鍵字的差異,在編譯期會視為相同方法簽章,無法定義為多載方法。
例:
在本範例中,並非傳遞 n 的值;而是傳遞 n 的參考。
class PassingValByRef { static void SquareIt(ref int x) { x *= x; System.Console.WriteLine("在方法內的變數值是: {0}", x); } static void Main() { // ref 參數傳遞前必須初始化; int n = 5; System.Console.WriteLine("呼叫方法前的變數值是: {0}", n); SquareIt(ref n); // 傳變數位址過去 System.Console.WriteLine("呼叫方法後的變數值是: {0}", n); } } /* Output: 呼叫方法前的變數值是: 5 在方法內的變數值是: 25 The value after calling the method: 25 */
3.以傳址方式交換二個實質型別的變數
建立一個方法交換x和y二個變數,呼叫它們並傳址過去,會改變真正的變數,達到交換的目的
static void SwapByRef(ref int x, ref int y) { int temp = x; x = y; y = temp; }
static void Main() { int i = 2, j = 3; System.Console.WriteLine("i = {0} j = {1}" , i, j); SwapByRef (ref i, ref j); System.Console.WriteLine("i = {0} j = {1}" , i, j); } /* Output: i = 2 j = 3 i = 3 j = 2 */
參考來源:
https://books.google.com.tw/books?id=3QjJAwAAQBAJ&pg=SA4-PA34&lpg=SA4-PA34&dq=c%23+%E5%82%B3%E5%80%BC%E5%91%BC%E5%8F%AB&source=bl&ots=xOveYIhO9R&sig=AiKZuAemq_lRkk-dNg8-cfYf4r4&hl=zh-TW&sa=X&ei=RG2SVN7KFIesmAX0-oLwCg&ved=0CCsQ6AEwAzgK#v=onepage&q=c%23%20%E5%82%B3%E5%80%BC%E5%91%BC%E5%8F%AB&f=false
http://www.dotblogs.com.tw/hunterpo/archive/2010/05/02/14978.aspx
http://msdn.microsoft.com/zh-tw/library/9t0za5es.aspx