今天在瀏覽博文時,看到這篇文章:C#中的ref 傳進出的到底是什麼 ? 在傳對象時使用ref的疑問
另附言:
本文寫於早上,就在想發布的那瞬間,靠,公司斷網了,原來修改的部分丟失了。
網一斷就是一天了,現在回到家才把之發布。
一直我們都知道,參考型別就傳的就是地址,實值型別傳的就是值,可是還仍有那麼多人迷惑,網上雖然流傳著很多ref 的相關文章,似乎都沒為大夥解下惑。
最近有人在看我 CYQ.Data 架構 的時候說起,既然class是引用地址,本身傳的就是地址,你代碼中還要寫ref傳遞來幹什麼;
原來以前明白的,被忽悠一下變不明白了,還以為自己原來的代碼寫錯了。
今天在幫人家解惑時,才把自己的惑給解了。
這裡我把上篇文章原問題的代碼小修改了一下
貼出來做樣本:
/// <summary>
/// by 路過秋天 http://cyq1162.cnblogs.com
/// </summary>
class Program
{
static void Main(string[] args)
{
Person p = new Person("張三");
Change(p);
Write(p.Name); //輸出的是張三 並不是李四
Change(p, "李四");
Write(p.Name);//輸出的是李四
Change(ref p);
Write(p.Name); //輸出的是王五
Console.ReadKey();
}
static void Change(Person p)
{
p = new Person("李四");
}
static void Change(Person p, string name)
{
p.Name = name;
}
static void Change(ref Person p)
{
p = new Person("王五");
}
}
這裡順便讓大夥看看是怎麼調試而解惑的。
F5運行:
1:我們運行到第一行代碼,斷點:
重點說明:
p地址:0x044becf8
2:我們運行到Change(p)內部中
重點說明:p地址發生變化:0x044becd0簡單說:你這內部的p和外面的p都不一樣,所以不會影響外面p的地址。
備忘p值的地址變化了,是因為斷點在第一行代碼時還沒執行執行個體化,所以其值是一樣的。
於是第一行結果輸出:張三
3:接下來運行到Change(p,"李四") 函數內部
重點說明:這裡內部的p的地址還是發生了變化,變成了0x044becd0
然而其指向的值是一樣的,所以你把值改了,所以“李四”就出來了。
備忘:
內部的p和外面的p雖然不一樣,但是指向的值是一樣的。
於是第一行結果輸出:李四
4:最後是 Change(ref p) 函數內部
重點說明:
這裡內部的p地址和外部的p地址是一樣的,沒有發生變化。
然後重新指向一個新的對象,只是對象的值地址發生了變化。
備忘:外部p地址=內部p地址,所以其指向的值都是新的對象的值。
於是第三行結果輸出:張三
最終結果圖如下:
最後結言:
對於Class類型使用 ref,是為了保持引用的地址是一致的。
所以,不要僅僅意識到參考型別傳地址,實值型別傳值就了事了,要切切的注意到,參考型別傳址時,內部傳參會產生一個新地址。
所以我們在傳遞類引用時,喜歡在內部使用 new的民工們得注意注意了。這裡似乎也是傳參領域的問題,只是附上了 ref 。