C# 引用型別作為值引數和引用引數
阿新 • • 發佈:2021-06-20
- 引用型別作為值型別傳遞,形參和實參其實是兩個指標,只不過指向的是同一塊記憶體。新
new
一個物件是,它們兩的聯絡就被切斷了,指向了不同的記憶體塊。 - 引用型別作為引用引數,此時的形參其實是實參的一個別名,它們兩個其實是一個指標,新
new
一個物件是,指向的還是同一記憶體塊,因為它們本身就是同一個指標。
兩種情況的最後指向是不一樣的。
以下情況是, 在方法內建立一個新物件並賦值給形參。
引用型別作為值引數
using System; namespace RefParameter { class MyClass { public int test = 20; } class Program { static private void RefparameterTest( MyClass mc) { mc.test = 50; Console.WriteLine("修改值之後:{0}", mc.test); mc = new MyClass(); Console.WriteLine("新建立之後:{0}", mc.test); } static void Main(string[] args) { MyClass mc = new MyClass(); Console.WriteLine("原始值:{0}\n=======", mc.test); RefparameterTest( mc); Console.WriteLine("=======\n最後值:{0}", mc.test); Console.ReadKey(); } } }
輸出:
原始值:20
=======
修改值之後:50
新建立之後:20
=======
最後值:50 // 被修改
引用型別作為引用引數
using System; namespace RefParameter { class MyClass { public int test = 20; } class Program { static private void RefparameterTest(ref MyClass mc) { mc.test = 50; Console.WriteLine("修改值之後:{0}", mc.test); mc = new MyClass(); Console.WriteLine("新建立之後:{0}", mc.test); } static void Main(string[] args) { MyClass mc = new MyClass(); Console.WriteLine("原始值:{0}\n=======", mc.test); RefparameterTest(ref mc); Console.WriteLine("=======\n最後值:{0}", mc.test); Console.ReadKey(); } } }
輸出:
原始值:20
=======
修改值之後:50
新建立之後:20
=======
最後值:20 // 是新 new 物件的預設值 20
如果不在方法內部改變引用形參的指向,他們操縱的記憶體區域是一樣的,結果也是一樣的。
using System; namespace RefTest { class Myclass { public int val = 10; } class Program { static void Mymethod(Myclass a, int b) // 看這裡 { a.val += 5; b += 5; } static void Main() { Myclass a = new Myclass(); int b = 20; Console.WriteLine($"呼叫前:a = {a.val}, b = {b}"); Mymethod(a, b); // 看這裡 Console.WriteLine($"呼叫後:a = {a.val}, b = {b}"); Console.ReadKey(); } } }
輸出:
呼叫前:a = 10, b = 20
呼叫後:a = 15, b = 20 // 可見 物件a的數值成員值改變了,值變數b沒有改變。
using System;
namespace RefTest
{
class Myclass
{
public int val = 10;
}
class Program
{
static void Mymethod(ref Myclass a, ref int b) // 看這裡
{
a.val += 5;
b += 5;
}
static void Main()
{
Myclass a = new Myclass();
int b = 20;
Console.WriteLine($"呼叫前:a = {a.val}, b = {b}");
Mymethod(ref a, ref b); // 看這裡
Console.WriteLine($"呼叫後:a = {a.val}, b = {b}");
Console.ReadKey();
}
}
}
輸出:
呼叫前:a = 10, b = 20
呼叫後:a = 15, b = 25 // 可見 都改變了。
參考: 《C#圖解教程》 -> P66