即使傳值方式,仍可能改變 Element 類別物件 t 的內容。嚴格說,我們改變的是物件 t 的欄位,而非 t 本身。
class Element { public int Number = 10; }
class Test
{
static void Change(Element s) { s.Number = 100; }
static void Main()
{
Element e = new Element();
Console.WriteLine(e.Number); // 10
Change(e);
Console.WriteLine(e.Number); // 100
}
}
class Element { public int Number = 10; }
class Test
{
static void Change(Element s)
{
Element r = new Element(); r.Number = 100;
s = r; // 僅改變區域參考 s,不影響呼叫端 e
}
static void Main()
{
Element e = new Element();
Console.WriteLine(e.Number); // 10
Change(e);
Console.WriteLine(e.Number); // 10 (未改變!)
}
}
關鍵差異:傳值過程中,參考型別本身不會改變(s 不變),但參考型別內含欄位會改變(s.Number 可修改)。C# 參考型別: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