裝箱與拆箱效能損耗詳解
阿新 • • 發佈:2019-01-08
拆箱是將引用型別轉換為值型別 ;反之,裝箱!
利用裝箱和拆箱功能,可通過允許值型別的任何值與Object 型別的值相互轉換,將值型別與引用型別連結起來 ;
例如: int val = 100;
object obj = val;
Console.WriteLine (“物件的值 = ",obj);
這是一個裝箱的過程,是將值型別轉換為引用型別的過程
int val = 100;
object obj = val;
int num = (int) obj;
Console.WriteLine ("num: ",num);
這是一個拆箱的過程,是將值型別轉換為引用型別,再由引用型別轉換為值型別的過程
顯然,從原理上可以看出,裝箱時,生成的是全新的引用物件,這會有時間損耗,也就是造成效率降低。看下面程式碼
class Program { static void Main(string[] args) { //// 用時:00:00:01.6070325(跟電腦執行效率有一定關係) //ArrayList list = new ArrayList(); //Stopwatch watch = new Stopwatch(); //watch.Start(); //for (int i = 0; i < 10000000; i++) //{ ////使用ArrayList集合,每次增加一個數字都會發生裝箱操作。 // list.Add(i); //} //watch.Stop(); //Console.WriteLine(watch.Elapsed); //Console.ReadKey();/ //用時:00:00:00.1402388,使用泛型集合後,省去了裝箱與拆箱操作,效能大大提升。 List<int> list = new List<int>(); Stopwatch watch = new Stopwatch(); watch.Start(); for (int i = 0; i < 10000000; i++) { list.Add(i); } watch.Stop(); Console.WriteLine(watch.Elapsed); Console.ReadKey(); } }
總結:
1.裝箱、拆箱必須是:值型別→引用型別 或 引用型別→值型別。
object,介面。值型別是可以實現介面。
Personp=new Student();//這個叫隱式型別轉換,不叫裝箱。
Studentstu=(Student)p;//這個叫顯示型別轉換,不叫拆箱。
int型別為什麼能裝箱到object型別,但不能裝箱到string型別或Person型別,
因為object型別時int型別的父類。
2.拆箱時,必須用裝箱時的型別來拆箱
裝箱時如果是int,拆箱必須用int,不能用double
3.方法過載時,如果具有該型別的過載,那麼就不叫拆箱或裝箱。4.字串連線
string s1 = "a";
string s2 = "b";
int n3 = 10;
double d4 = 99.9;
string result = string.Concat(s1, s2, n3, d4);
//string.Concat(s1,s2, n3, d4); 判斷是否發生了裝箱,及次數。
反編譯IL程式碼如下圖:可以得出發生了兩次裝箱吧。