[C#] 基礎 - Value Type , Reference Type 用看記憶體內容 來測試

實值型別,參考型別 用看記憶體內容 來測試
使用Visual Studio 2015 Community 

前言

請先在debug中打開
偵錯 -> 視窗 -> 即時視窗
偵錯 -> 視窗 -> 記憶體
偵錯 -> 視窗 -> 暫存器
建議可以這樣排列視窗

Value Type記憶體內容

public void Demo1()
{
    var i = 5;
    var o = new Order()
    {
        ID = 9,
        Name = 'a'
    };

    Method(o,i);
    Console.WriteLine(i);
    Console.WriteLine(o.ID);
    Console.WriteLine(o.Name);
}

private void Method(Order no, int ni)
{
    ni = 6;
    no.ID = 10;
    no.Name = 'b';       
}

public class Order
{
    public int ID { get; set; }
    public char Name { get; set; }
}

測試程式碼如上 請執行Debug模式
中斷點下在Method(o,i);
等停在中斷點時 即時視窗輸入 &i
0x06ffe8dc 就是變數i 記憶體位置
請在記憶體1視窗輸入0x06ffe8dc 後 按Enter

看到記憶體內容05 也就是程式碼給的5
來確認一下是否真的是這個位子
請在監看式 將i的值改成11 並觀察 記憶體的內容是否改變
可以看到記憶體內容 已經被改成0b(16進位)
對了 這邊的記憶體位置 就是Stack 
 

Reference Type記憶體內容

即時視窗輸入 &o
o 是自訂物件order 所以0x079eebc8 stack記憶體
又指到 49148504(這邊是10進位 要自己轉16進位 02EDF258 不過暫存器的EAX 應該就是)
02EDF258 就是 Heap
一樣來確認一下是否真的是這個位子 不過這是直接改記憶體 把09改10 , 61 改71
可以看到監看式的內容有改變果然沒錯
(這就是遊戲可以修改金錢的道理)

整理目前變數

觀察呼叫方法時

回到程式碼按一下F11 進入到Method(Order no, int ni)
即時視窗輸入 &ni  跟 &no
會看到產生出兩組新的記憶體位置 不過 &no的stack 還是參考回 49148504 (02EDF258 16進位)
這時將程式碼執行到最後一行觀察輸出視窗
實質型別 還是5
參考型別 卻已經是方法裡面改過的值
原因剛剛已經有提到了
因為是&o &no 都是參考回同一個Heap記憶體位置

整理目前變數

觀察用ref 參數

private void RefMethod(ref Order ro, ref int ri)
{
    ri = 7;
    ro.ID = 11;
    ro.Name = 'c';
}

程式碼改呼叫RefMethod(ref Order no, ref int ni)
一樣在進入方法前 先觀察  &i  跟 &o  跟進入方法後 &ri  跟 &ro

可以看到是相同的記憶體位置 就是因為用ref 參數
所以 才能達到實質型別 將方法內修改的內容會持續到原程式
至於 參考型別 加上ref 就是測試用 通常是不會加上ref
結果就是都改了
 
整理目前變數

結語

用記憶體內容來觀察一些基礎知識
可以讓一些死背的結果
更加理解 加深記憶

完整程式碼放在 Github了 - 請看A00_Basis資料夾

如果內容有誤請多鞭策謝謝