C#學習筆記(基礎知識回顧)之值類型和引用類型
1.1,C#數據類型分為在棧上分配內存的值類型和在托管堆上分配內存的引用類型。如果int只不過是棧上的一個4字節的值,該如何在它上面調用方法?
2.1CLR對值類型進行裝箱時:新分配托管堆內存,將值類型的實例字段拷貝到新分配的內存中,返回托管堆中新分配對象的地址。這個地址就是一個指向對象的引用。
int i = 10; Object obj = i;
3.1只能對以前裝箱的變形進行拆箱,拆箱是將對象轉換為原來的類型
int i = 10; Object obj = i; int j = (int)obj;
4.1一種最普通的場景是,調用一個含類型為Object的參數的方法,該Object可支持任意為型,以便通用。當你需要將一個值類型傳入時,需要裝箱。例如:AddOne接收一個Object類型參數,如果是int32類型則數值加1,如果是string類型則加字符串“1”。
static void Main(string[] args) { int i = 10; string str = "10"; Console.WriteLine(AddOne(i));//輸出11 Console.WriteLine(AddOne(str));//輸出101 Console.ReadKey(); } public static string AddOne(Object o) { if (o.GetType() == typeof (Int32)) { return ((int) o + 1).ToString(); } else if(o.GetType()==typeof(String)) { return o+ "1"; } else { return "1"; } }
4.2另一種用法是,一個非泛型的容器,同樣是為了保證通用,而將元素類型定義為Object。於是,要將值類型數據加入容器時,需要裝箱。例如:
var array = new ArrayList(); array.Add(1); array.Add("2"); foreach (var value in array) { Console.WriteLine("value is {0}", value); } //結果輸出是:value is 1 // value is 2 Console.ReadKey();
從原理上可以看出,裝箱時,生成的是全新的引用對象,這會有時間損耗,也就是造成效率降低。
所以,應該盡量避免裝箱。
比如4.1的情況可以通過方法重載避免,4.2盡量使用泛型規避裝箱拆箱操作。