資料在記憶體中的儲存位置,取決於它的資料類型,在C#中,分為實值型別和參考型別,實值型別的資料存放區在記憶體中的堆棧中,每個變數或程式都有自己的堆棧,不可以共用一個堆棧地址。當資料一個實值型別的變數傳遞到另一個相同類型的變數時,會在堆棧中分配兩個不同的地址。
而參考型別的資料存放區在記憶體中的堆中,可以不同的變數或程式共同使用同一個位置的資料。當資料從一個參考型別的變數傳遞到另一個相同類型的變數時,只是把這個變數的引用地址傳遞給新的變數,同時引用當前堆中儲存的資料。
可以通過執行個體得到詳細結論:using System;
using System.Collections.Generic;
using System.Text;
namespace RefRectangle
{
class RefRectangle
{
//定義一個矩形類 屬於參考型別
public int width;
public int height;
}
//定義一個矩形結構 屬於實值型別
struct ValRectangle
{
public int width;
public int height;
}
class RefValRectangle
{
public static void Main()
{
//建立矩形對象 並將值傳遞給另一個新對象
RefRectangle ref1 = new RefRectangle();
ref1.width = 3;
ref1.height = 4;
RefRectangle ref3 = ref1;
Console.WriteLine("Dimensions of ref are:" + ref3.width.ToString() + "" +ref3.height.ToString());
Console.WriteLine("change dimensions of ref1");
ref1.width = 10;
ref1.height = 50;
bool bTransfer = ref3.Equals(ref1);
Console.WriteLine("Dimensions of ref1 now are :"+ ref3.width.ToString() +"." +ref3.width.ToString());
Console.WriteLine(bTransfer.ToString());
Console.ReadLine();
//建立一個新的矩形結構,將值傳遞給一個新的矩形結構
ValRectangle val1 = new ValRectangle();
val1.width = 3;
val1.height = 4;
ValRectangle val3 = val1;
Console.WriteLine("Dimensions of val are:" + val3.width.ToString() +""+ val3.height.ToString());
Console.WriteLine("Change Dimensions of val1");
val1.height = 10;
val1.height = 50 ;
bool bPass = val3.Equals(val1);
Console.WriteLine("Dimensions of val1 now are : " + val3.width.ToString() + ".." + val3.height.ToString());
Console.WriteLine(bPass.ToString());
Console.ReadLine();
}
}
}
可以看到,當實值型別的變數傳遞後,改變第一個變數,不會影響第二個變數的值,這是因為,當變數傳遞時,是在堆棧中又分配了一個地址給新的變數,所以這個兩個變數在傳遞發生後,不再有關係。
而參考型別的變數傳遞後,改變第一個,第二個變數隨之改變,是因為兩個變數同時引用堆中的一個地址的內容,當一個變數改變,對應與記憶體中的堆也隨之改變,而另外的一個變數也隨之改變。