分析C#中b=a的多種情況及結(jié)果
在這里我們將介紹#中b=a的多種情況及結(jié)果,希望通過本文仔細(xì)做好兩個(gè)變量中,一個(gè)改變而另一個(gè)的狀態(tài),希望對大家有所幫助。
本文旨在驗(yàn)證一個(gè)容易混淆的概念,從而為《玩轉(zhuǎn)WPF/Silverlight中INotifyPropertyChanged和ObservableCollection》做鋪墊。
兩個(gè)相同類型的變量a和b,并且有如下關(guān)系:
b=a;
如果a發(fā)生改變,b是否也發(fā)生改變呢?
情況很復(fù)雜,分以下幾種情況談?wù)摚?/P>
1) 單個(gè)實(shí)體
1. 簡單類型
先考察int:
輸出結(jié)果:
- inta=1;
- intb=a;
- a=2;
- Console.WriteLine("b:"+b);
再考察一下string:
輸出結(jié)果:
- stringa="1";
- stringb=a;
- a="2";
- Console.WriteLine("b:"+b);
如果不放心,還可以測試一下Enum,結(jié)果類似,詳見Demo。
結(jié)論:簡單類型是組成復(fù)合類型的最基本單位,是原子,不可再拆分,所以不管是值類型double、int還是引用類型string,b都不隨a的改變而改變,因?yàn)樗鼈冎赶蛉侄褩#▽τ趕tring而言是托管堆)上的同一個(gè)地址。
2. 復(fù)合類型
復(fù)合類型是由string、int、double這些簡單類型組成的。
分別定義一個(gè)復(fù)合的引用類型(class)和一個(gè)復(fù)合的值類型(struct)。
- classUserInfo
- {
- publicstringUserName;
- publicintAge;
- }
- structUserInfo2
- {
- publicstringUserName;
- publicintAge;
- }
先討論引用類型:
輸出結(jié)果:
- UserInfoa=newUserInfo(){UserName="Baobao",Age=27};
- UserInfob=a;
- a.UserName="AndersLiu";
- a.Age=30;
- Console.WriteLine("b.UserName:"+b.UserName);
- Console.WriteLine("b.Age:"+b.Age);
結(jié)論:b和a仍然指向托管堆上的同一個(gè)UserInfo實(shí)例的地址。而UserInfo實(shí)例的成員又包含著UserName和Age分別在托管堆和全局堆棧上的地址。所以修改a的成員UserName和Age,只是改變這兩個(gè)成員的地址,而沒有改變UserInfo實(shí)例的地址,所以b的成員UserName和Age也會跟著改變。
讓我們局部修改上面的代碼:
輸出結(jié)果:
- UserInfoa=newUserInfo(){UserName="Baobao",Age=27};
- UserInfob=a;
- //a.UserName="AndersLiu";
- //a.Age=30;
- a=newUserInfo(){UserName="AndersLiu",Age=30};
- Console.WriteLine("b.UserName:"+b.UserName);
- Console.WriteLine("b.Age:"+b.Age);
結(jié)論:對a重新進(jìn)行實(shí)例化,導(dǎo)致a指向一個(gè)新的UserInfo實(shí)例的地址。而b仍然指向原先那個(gè)UserInfo實(shí)例的地址,所以b不會隨著a的改變而改變。從此b和a是兩個(gè)沒有任何關(guān)系的變量。
再來看一下值類型:
輸出結(jié)果:
- UserInfo2a=newUserInfo2(){UserName="Baobao",Age=27};
- UserInfo2b=a;
- a.UserName="AndersLiu";
- a.Age=30;
- Console.WriteLine("b.UserName:"+b.UserName);
- Console.WriteLine("b.Age:"+b.Age);
結(jié)論:問題集中在b=a這句話上。這時(shí)b指向的是a的一份copy,指向全局堆棧上的與a不同的地址。所以b和a是沒有任何關(guān)系的,b不隨a的改變而改變。
2) 集合
1.集合中一筆數(shù)據(jù)的增刪修改。
輸出結(jié)果:
- List<UserInfo>a=newList<UserInfo>();
- List<UserInfo>b=a;
- a.Add(newUserInfo(){UserName="Baobao",Age=27});
- Console.WriteLine("b.Countafteradding:"+b.Count);
- Console.WriteLine();
- Console.WriteLine("Aftermodifyinga[0]");
- a[0].UserName="AndersLiu";
- a[0].Age=30;
- Console.WriteLine("b[0].UserName:"+b[0].UserName);
- Console.WriteLine("b[0].Age:"+b[0].Age);
- Console.WriteLine();
- a.Remove(a[0]);
- Console.WriteLine("b.Countafterdeleting:"+b.Count);
結(jié)論:b隨著a中數(shù)據(jù)增減修改而變化。因?yàn)閎和a指向托管堆上同一個(gè)List
數(shù)組就不說了,可以看作是多個(gè)變量的集合,所以按照集合來處理。寫了幾段測試代碼,放在Demo中。
原文標(biāo)題:對于C#中b=a的N種情況分析
鏈接:http://www.cnblogs.com/Jax/archive/2009/10/12/1581725.html
【編輯推薦】