看看下面的程序
using System;
namespace AccessProject
{
class Program
{
public static void swap(int a,int b)
{
int temp = a;
a = b;
b = temp;
}
static void Main(string[] args)
{
int a = 10;
int b =20;
swap(a,b);
Console.WriteLine("a=" + a);
Console.WriteLine("b=" + b);
}
}
}
輸出結果: a=10
b =20
這個例子裏面,執行玩函數swap後,a,b的值都沒有發生變化
接着看這個例子:
using System;
namespace AccessProject
{
public class A
{
internal int m;
public A(int m)
{
this.m = m;
}
public void fun(A a)
{
this.m = a.m;
}
}
class Program
{
static void Main(string[] args)
{
A a = new A(10);
A b = new A(20);
a.fun(b);
Console.WriteLine("a.m="+a.m);
}
}
}
輸出結果是: a.m=20
這個例子裏面,a執行完函數後,狀態發生了改變
從這兩個例子可以看出,c#的方法在處理參數的時候,和java一樣,採用的是值調用的方法。對於值類型的數據(int ,float,double)等基本數據類型,參數傳遞過來後,形參和實參是兩個不同的數據存儲單元,因此,在函數裏對形參進行處理後,並不影響實參。所以在函數處理完後,實參仍然是原來的值。而對於引用型的數據類型,如class,則實參傳遞進來後,儘管形參和實參是兩個不同的存儲單元,但是由於是引用類型,因此形參和實參都指向的是同一個地址。所以在函數裏面對形參的處理實際上就是對實參的處理。所以函數返回後,實參的狀態發生了變化。
我們最後再看這個例子:
using System;
namespace AccessProject
{
public class A
{
public void fun1(string s)
{
s = "HUST";
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
string s = "HUSTCS";
a.fun1(s);
Console.WriteLine("s="+s);
}
}
}
這裏形參和實參在函數調用剛開始的時候都只向同一個存儲地址,但是後面語句s="HUST"執行後,形參已經指向一個新的存儲地址了,實際上形參和實參已經脫鉤了,所以最後的輸出結果爲s=HUSTCS
這上面的處理機制和JAVA的機制是一致的,下面是C#的新增的部分
值調用的方式爲形參和實參開闢了兩個不同的存儲區域,如果希望形參和共用一塊存儲空間怎麼辦,只要在形參前加上關鍵字 ref即可,值得注意的是,形參前面有ref關鍵字修飾的話,實參前也必須由關鍵字ref相對應
另外,C#裏增加了新的帶出參數這一部分,也就是說,C#允許某個參數將程序的運行結果帶回來,這在一個函數需要返回多個值的時候特別有用處。