本篇所寫都是本人想當(dāng)然的理解。如果這種理解便于幫助你理解一些知識的話,我會感到由衷的欣慰。 .net中雖然沒有指針語法,但是在堆中分配對象,將引用放在棧中,十分類似C++中的指針操作,此時(shí)引用就可以看成一種特殊的指針。因?yàn)橹羔槻僮鞯拈g接性,會帶來一定的性能影響,為了避免這種影響,.net采取了一種折衷的辦法,引入了值類型。 為了在值類型和引用類型之間進(jìn)行一些合理的轉(zhuǎn)換,于是帶來了裝箱和拆箱。 裝箱簡單來說就是將值類型轉(zhuǎn)換為引用類型。按三步進(jìn)行: (1)新分配托管堆內(nèi)存(大小為值類型實(shí)例大小加上一個(gè)方法表指針和一個(gè)SyncBlockIndex)。 (2)將值類型的實(shí)例字段拷貝到新分配的內(nèi)存中。 (3)返回托管堆中新分配對象的地址。 拆箱就是將引用類型轉(zhuǎn)換為對應(yīng)的值類型。分如下步驟進(jìn)行:(1)檢查引用對象實(shí)例,確保它是給定值類型的一個(gè)裝箱值。(2)獲取引用對象中指向值類型部分的指針。(3)將引用對象中對應(yīng)的內(nèi)容拷貝到值類型區(qū)域。 從上面步驟可以看出,裝箱和拆箱會給程序的性能帶來一定的影響,所以我們應(yīng)盡可能地避免裝箱和拆箱。裝箱可以隱式進(jìn)行,拆箱只能顯式進(jìn)行。只有先裝箱,才能拆箱。為了盡可能地避免裝箱和拆箱,我們需要了解裝箱的幾種情況。我總結(jié)了以下幾種(可能不太全面):(1)方法中參數(shù)為Object類,但是傳遞一個(gè)值類型。
(2)一個(gè)類型中有field申明為Object類,賦予一個(gè)值類型。
(3)調(diào)用Object類中沒有被值類型覆蓋的方法,如GetType()。
(4)將值類型轉(zhuǎn)換為成一個(gè)被該值類型實(shí)現(xiàn)的接口類型。
針對以上四種情況,為了減少裝箱和拆箱,建議以如下形式進(jìn)行:(1)方法中參數(shù)為Object類,但是傳遞一個(gè)值類型。 建議利用方法重載或者泛型。(2)一個(gè)類型中有field申明為Object類,賦予一個(gè)值類型。 建議利用泛型。(3)調(diào)用Object類中沒有被值類型覆蓋的方法,如GetType()。根據(jù)實(shí)際情況,判斷是否有其它方法實(shí)現(xiàn),如上面舉的例子就可以這樣修改:
(4)將值類型轉(zhuǎn)換為成一個(gè)被該值類型實(shí)現(xiàn)的接口類型。如果設(shè)計(jì)上真要求這么做,那可能只能如此了。我暫時(shí)沒有想到什么解法,如果你有更好的解法,希望不吝賜教。
posted on 2009-04-27 23:24 五味雜陳 閱讀(1743) 評論(1) 編輯 收藏 引用 所屬分類: .NET
Powered by: C++博客 Copyright © 五味雜陳