1、 引用類型的變量只包含對象所在的內存地址,將要復制的是內存地址而不是對象本身,所以對底層對象的修改會保留。
unsafe class Program
{
static void Main(string[] args)
{
Employee myE = new Employee() { id=4};
fixed (int* pId=&(myE.id))
{
Console.WriteLine("方法執行前,myE中id的地址為0x{0:X},值為{1}", (uint)&(*pId), (uint)*pId);
}
testMethod(myE);
fixed (int* pId = &(myE.id))
{
Console.WriteLine("方法執行後,myE中id的地址為0x{0:X},值為{1}", (uint)&(*pId), (uint)*pId);
}
Console.ReadLine();
}
static void testMethod(Employee myE)
{
myE.id = 5;
//myE = new Employee() { id = 5 };
fixed (int* pId = &(myE.id))
{
Console.WriteLine("方法執行中,myE中id的地址為0x{0:X},值為{1}", (uint)&(*pId), (uint)*pId);
}
}
}
輸出為:
方法執行前,myE中id的地址為0x1AF5BE0,值為4
方法執行中,myE中id的地址為0x1AF5BE0,值為5
方法執行後,myE中id的地址為0x1AF5BE0,值為5
執行過程為:
1) 在堆中新建對象myE,在棧中建立指向myE的指針
2) 按引用傳遞,所以在棧中新建指針,復制上面指針的地址,也指向myE
如下圖所示:
2、 如果在方法內部將內存地址指向一個新對象,則方法結束後在方法中所作的修改會被丟棄(原指針仍指向原對象,方法參數指向新對象,結束後一起銷毀)。
unsafe class Program
{
static void Main(string[] args)
{
Employee myE = new Employee() { id=4};
fixed (int* pId=&(myE.id))
{
Console.WriteLine("方法執行前,myE中id的地址為0x{0:X},值為{1}", (uint)&(*pId), (uint)*pId);
}
testMethod(myE);
fixed (int* pId = &(myE.id))
{
Console.WriteLine("方法執行後,myE中id的地址為0x{0:X},值為{1}", (uint)&(*pId), (uint)*pId);
}
Console.ReadLine();
}
static void testMethod(Employee myE)
{
//myE.id = 5;
myE = new Employee() { id = 5 };
fixed (int* pId = &(myE.id))
{
Console.WriteLine("方法執行中,myE中id的地址為0x{0:X},值為{1}", (uint)&(*pId), (uint)*pId);
}
}
}
輸出為:
方法執行前,myE中id的地址為0x1E77BE0,值為4
方法執行中,myE中id的地址為0x1E78E24,值為5
方法執行後,myE中id的地址為0x1E77BE0,值為4
執行過程為:
1) 在堆中新建對象myE,在棧中建立指向myE的指針
2) 按引用傳遞,所以在棧中新建指針,復制上面指針的地址,也指向myE
3) 方法中new一個新對象時,在堆中新建對象,並把地址傳給指針2