ref (C# 參考)
ref 關鍵字會導致引數由參考加以傳遞,而非透過值。 由參考傳遞的效果,是呼叫方法中參數的任何變更,都會反映在呼叫方法中。 例如,如果呼叫端傳遞了區域變數運算式或陣列元素存取運算式,且被呼叫的方法取代了 ref 參數所參考的物件,則呼叫端的區域變數或陣列元素現在會參考新的物件。
注意事項 |
---|
請勿將參考傳遞的概念與參考類型的概念相混淆。兩個概念並不相同。方法參數可以由 ref 修改,而不論其是否為實值類型或參考類型。當實值類型由參考傳遞時,沒有 boxing。 |
若要使用 ref 參數,方法定義和呼叫方法都必須明確使用 ref 關鍵字,如下列範例所示。
class RefExample
{
static void Method(ref int i)
{
// Rest the mouse pointer over i to verify that it is an int.
// The following statement would cause a compiler error if i
// were boxed as an object.
i = i + 44;
}
static void Main()
{
int val = 1;
Method(ref val);
Console.WriteLine(val);
// Output: 45
}
}
傳遞至 ref 參數的引數,在傳遞之前必須先初始化。 這點與 out 參數不同,其引數不需要在傳遞之前先明確初始化。 如需詳細資訊,請參閱 out。
類別的成員不能擁有僅在 ref 和 out 方面不同的簽章。 如果類型的兩個成員之間唯一的區別在於其中一個具有 ref 參數,而另一個具有 out 參數,則編譯器會發生錯誤。 例如,下列程式碼不會進行編譯。
class CS0663_Example
{
// Compiler error CS0663: "Cannot define overloaded
// methods that differ only on ref and out".
public void SampleMethod(out int i) { }
public void SampleMethod(ref int i) { }
}
不過,當一種方法具有 ref 或 out 參數,而另一種方法具有實值參數時,可以完成多載,如下列範例所示。
class RefOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(ref int i) { }
}
在需要簽章比對的其他情況 (如隱藏或覆寫) 下,ref 和 out 是簽章的一部分,而且彼此不相符。
屬性不是變數。 它們都是方法,且不能傳遞給 ref 參數。
如需如何傳遞陣列的詳細資訊,請參閱使用 ref 和 out 傳遞陣列 (C# 程式設計手冊)。
您不能將 ref 和 out 關鍵字用於下列幾種方法:
使用 async 修飾詞定義的非同步方法。
Iterator 方法,其包括 yield return 或 yield break 陳述式。
範例
前一個範例會示範當您由參考傳遞實值類型時,會發生什麼事。 您也可以使用 ref 關鍵字,來傳遞參考類型。 由參考傳遞參考類型,可讓被呼叫的方法取代該參考參數所參考之呼叫方法中的物件。 物件的儲存位置會以參考參數值的方式,傳遞至方法。 如果您變更參數儲存位置中的值 (指向新的物件),則也會變更呼叫端所參考的儲存位置。 下列範例會以 ref 參數,傳遞參考類型的執行個體。 如需如何由實值及參考來傳遞參考類型的詳細資訊,請參閱傳遞參考類型的參數 (C# 程式設計手冊)。
class RefExample2
{
static void ChangeByReference(ref Product itemRef)
{
// The following line changes the address that is stored in
// parameter itemRef. Because itemRef is a ref parameter, the
// address that is stored in variable item in Main also is changed.
itemRef = new Product("Stapler", 99999);
// You can change the value of one of the properties of
// itemRef. The change happens to item in Main as well.
itemRef.ItemID = 12345;
}
static void Main()
{
// Declare an instance of Product and display its initial values.
Product item = new Product("Fasteners", 54321);
System.Console.WriteLine("Original values in Main. Name: {0}, ID: {1}\n",
item.ItemName, item.ItemID);
// Send item to ChangeByReference as a ref argument.
ChangeByReference(ref item);
System.Console.WriteLine("Back in Main. Name: {0}, ID: {1}\n",
item.ItemName, item.ItemID);
}
}
class Product
{
public Product(string name, int newID)
{
ItemName = name;
ItemID = newID;
}
public string ItemName { get; set; }
public int ItemID { get; set; }
}
// Output:
//Original values in Main. Name: Fasteners, ID: 54321
//Back in Main. Name: Stapler, ID: 12345
C# 語言規格
如需詳細資訊,請參閱<C# 語言規格>。語言規格是 C# 語法及用法的限定來源。