C# 中的數據有兩種類型:引用類型(reference types)和值類型(value types)。 簡單類型(包括int, long, double等)和結構(structs)都是值類型,而其他的類都是引用類型。 簡單類型在傳值的時候會做複製操作,而引用類型只是傳遞引用,就像 C++ 中的指針一樣。
ref 關鍵字使參數按引用傳遞。其效果是,當控制權傳遞迴調用方法時,在方法中對參數所做的任何更改都將 反映在該變量中。
若要使用 ref 參數,則方法定義和調用 方法都必須顯式使用 ref 關鍵字.
例(轉):
public class MyClass
{
public int Value;
}
// ----------------------------------------
// Tester methods
public static void TestRef(ref MyClass m1)
{
// 這裏的 m1 也就相當於大家所說的指向指針的指針:
// m1 指向 Main 中的 m,而 m 則指向那個實際的 MyClass 的實例
// 相當於 C++ 中的
// MyClass** m1 = &m;
// (*m1)->Value = 10;
//
m1.Value = 10;
}
public static void TestNoRef(MyClass m1)
{
// 這裏是一個普通的傳遞引用類型的例子。相當於:
// MyClass m1 = m;
// m1.Value = 20;
//
// m1 複製了 m 中的內容,也就是說現在 m1 也和 m 一樣,指向了 m 指向的實例
// 所以這裏對 m1 的修改也會影響到 Main 中的 m。
//
m1.Value = 20;
}
public static void TestCreateRef(ref MyClass m1)
{
// 這裏的 m1 也是一個指向引用的引用:
// m1 指向 Main 中的 m,而 m 則指向那個實際的 MyClass 的實例
// 相當於 C++ 中的
// MyClass** m1 = &m;
// *m1 = new MyClass();
// (*m1)->Value = 100;
// 在上面的 *m1 = new MyClass() 這個調用的時候,實際上只是將 Main 中 m 的值(引用)給修改了,
// 也就是說現在 m1 指向 Main 中的 m,而 m 現在則指向了這個新生成的實例。
// 所以這裏 m1.Value = 100 是會影響到 Main 中的結果的
//
m1 = new MyClass();
m1.Value = 100;
}
public static void TestCreateNoRef(MyClass m1)
{
// 在這個方法裏面,我們新申明瞭一個 MyClass 的實例,而讓 m1 指向了這個實例
// 這時候,實際上將 m1 的值修改了, m1 和 Main 中的 m 各自指向不同的實例
// 所以對 m1 做的任何修改都不會影響到 m 了
//
m1 = new MyClass();
m1.Value = 200;
}
public static void Main()
{
MyClass m = new MyClass();
m.Value = 1;
TestRef(ref m);
Console.WriteLine(m.Value);
TestNoRef(m);
Console.WriteLine(m.Value);
TestCreateRef(ref m);
Console.WriteLine(m.Value);
TestCreateNoRef(m);
Console.WriteLine(m.Value);
}
例二:
[STAThread]
static void Main(string[] args)
{
TempClass m_class1 = new TempClass();
m_class1.m_member = 0;
TempClass m_class2 = m_class1;
TempClass m_class3 = m_class1;
TempClass m_class4 = m_class1;
ChangeData2(ref m_class2, m_class2); //m_class1.m_member:0; m_class2.m_member:41
ChangeData3(m_class3); //m_class3.m_member:0
ChangeData4(ref m_class4); //m_class4.m_member:44
}
static void ChangeData2(ref TempClass i_obj1,TempClass i_obj2)
{
i_obj1 = new TempClass();
i_obj1.m_member = 41;
i_obj2 = new TempClass();
i_obj2.m_member = 42;
}
static void ChangeData3(TempClass i_obj1) //相當於值傳遞了
{
i_obj1 = new TempClass();
i_obj1.m_member = 43;
}
static void ChangeData4(ref TempClass i_obj1)
{
i_obj1 = new TempClass();
i_obj1.m_member = 44;
}
}
class TempClass
{
public int m_member;
}