我們看到即使傳值方式仍然改變了類型為Element類的對象t。但嚴格意義上講,我們是改變了對象t的域,而非對象t本身。我們再看下面的例子:
using System;
class Element
{
public int Number=10;
}
class Test
{
static void Change(Element s)
{
Element r=new Element();
r.Number=100;
s=r;
}
static void Main()
{
Element e=new Element();
Console.WriteLine(e.Number);
Change(e);
Console.WriteLine(e.Number);
}
}
程序經編譯後執行輸出:
10
10
傳值方式根本沒有改變類型為Element類的對象t!實際上,如果我們能夠理解類這一C#中的引用類型(reference type)的特性,我們便能看出上面兩個例子差別!在傳值過程中,引用類型本身不會改變(t不會改變),但引用類型內含的域卻會改變(t.Number改變了)!C#語言的引用類型有:object類型(包括系統內建的class類型和用戶自建的class類型--繼承自object類型),string類型,interface類型,array類型,delegate類型。它們在傳值調用中都有上面兩個例子展示的特性。
在傳值和傳址情況下,C#強制要求參數在傳入之前由用戶明確初始化,否則編譯器報錯!但我們如果有一個並不依賴於參數初值的函數,我們只是需要函數返回時得到它的值是該怎麼辦呢?往往在我們的函數返回值不至一個時我們特別需要這種技巧。答案是用out修飾的輸出參數。但需要記住輸出參數與通常的函數返回值有一定的區別:函數返回值往往存在堆棧裡,在返回時彈出;而輸出參數需要用戶預先制定存儲位置,也就是用戶需要提前聲明變量--當然也可以初始化。看下面的例子:
using System;
class Test
{
static void ResoluteName(string fullname,out string firstname,out string lastname)
{
string[] strArray=fullname.Split(new char[]{' '});
firstname=strArray[0];
lastname=strArray[1];
}
public static void Main()
{
string MyName="CornfIEld Lee";
string MyFirstName,MyLastName;
ResoluteName(MyName,out MyFirstName,out MyLastName);
Console.WriteLine("My first name: {0}, My last name: {1}",
MyFirstName, MyLastName);
}
}
程序經編譯後執行輸出:
My first name: CornfIEld, My last name: Lee