《 Ne框架程式設計》隨記 4

2021-09-22 10:37:46 字數 2116 閱讀 5990

問:這段**裡有多少次裝箱操作?

這裡首先建立了乙個未裝箱的int值型別(v),並將其初始化為4,然後,又建立了乙個object引用型別(o),並希望將其指向v,但是因為引用型別必須指向託管堆中的物件,所以會產生適當的il**將v進行裝箱,並將v的裝箱「拷貝」的位址存放在o中,隨後123被放入未裝箱的值型別v中,這對已經裝箱的int值沒有任何影響,它的值還是4。

接著,**中呼叫了writeline方法,writeline方法期望的引數是乙個string物件,但**中沒有,反而只有3個物件:乙個未裝箱的int值型別(v),乙個string(引用型別),以及乙個指向已經裝箱的int值型別(o)的引用,並且這個已經裝箱的值型別正被轉型為乙個未裝箱的int型別,這3個物件必須被組合為乙個string物件。

為了將3個物件組合為乙個string物件,會呼叫string的靜態concat方法,public static string concat(object arg0, object arg1, object arg2);所以v必須被裝箱,最後乙個變數o首先被轉型為乙個int型,再被裝箱,最後裝箱後的記憶體位址才會被傳遞給arg2。 

public static void main(string args)

這裡又發生了幾次裝箱?是1次。這是因為system.console類中定義了乙個接受int型別引數的writeline方法,public static void writeline(system.int32 value);因此上面方法呼叫中的v(未裝箱值型別例項)以傳值的方式被傳遞。

如果我們知道自己寫的**會導致編譯器反覆地對乙個值型別進行裝箱,那麼我們應該自己來做這樣的裝箱操作,這樣就可以能夠減少生成的**量,並且提高**執行速度。

using system;

,,",v,v,v);

#else

object o = v;//手動裝箱一次

//編譯下面**將不會再出現裝箱

console.writeline(",,",o,o,o);

#endif         }

}若定義了inefficient符號,那麼編譯器將對v執行3次裝箱,從而導致在託管堆上分配3個物件,這當然很浪費記憶體和時間。若沒有inefficient符號,那麼編譯器將對v只執行1次裝箱,只會在託管堆上分配1個物件,最後這個被裝過箱的int 值分3次傳遞給console.writeline()方法,顯然,這要比前者分配的記憶體要少,執行速度更快。

using system;

struct point : icloneable

, )", x, y); }

// implementation of icloneable』s clone method

public object clone() 

}

} 在呼叫tostring時,p不會被裝箱,因為tostring是乙個繼承自system.valuetype的方法,正常情況下,呼叫乙個從基類繼承而來的方法,我們需要乙個指向其型別方法表的指標,而p是乙個未裝箱的值型別,它沒有指向point方法表的指標,但是,編譯器會發現point重寫了tostring方法,它將產生直接呼叫tostring的指令,因為point是乙個值型別,而值型別不會被用作任何其他型別的基型別。所以編譯器就知道這裡不會出現多型行為。

在呼叫gettype()時,p必須被裝箱。因為point型別沒有提供gettype方法的實現,而是直接繼承了system.valuetype的gettype方法,所以在呼叫gettype()時,我們必須有乙個指向point方法表的指標,而這就只能夠通過對p進行裝箱來獲得。

在第1次呼叫clone時,p不必被裝箱,因為point實現了clone方法,編譯器可以直接呼叫它。clone返回時的是乙個object,它是乙個指向託管堆上已裝箱的point物件的引用。要將其內的字段拷貝到未裝箱的值型別p2中,就必須執行拆箱操作。

而要把p2轉型為icloneable介面型別時,p2必須要被裝箱,因為介面是一種引用型別,而裝箱後的指標被存放在c中。

在第2次呼叫clone方法時,不會出現裝箱操作,clone方法將直接在託管堆中已裝箱的物件上被呼叫。clone在託管堆上建立乙個新物件,並且返回指向這個物件的引用,該引用被儲存在變數o中。

在o轉型為point時,o所引用的物件會執行拆箱操作,其中的字段會被從託管堆拷貝到變數p中,p是乙個駐留在堆疊上的point值型別例項

《 Ne框架程式設計》隨記 3

以往,每個應用程式程序都有自己的虛擬位址空間,通過位址空間的隔離來保證乙個程序不會干擾另乙個程序的執行。但通過驗證託管 可以確保不會訪問不該訪問的記憶體,因此可以乙個單獨的虛擬位址空間內執行多個託管應用程式。由於太多的程序會占用過多的系統資源,損傷系統效能,並限制系統可用的資源。因此在乙個程序中執行...

《 Ne框架程式設計》隨記 3

以往,每個應用程式程序都有自己的虛擬位址空間,通過位址空間的隔離來保證乙個程序不會干擾另乙個程序的執行。但通過驗證託管 可以確保不會訪問不該訪問的記憶體,因此可以乙個單獨的虛擬位址空間內執行多個託管應用程式。由於太多的程序會占用過多的系統資源,損傷系統效能,並限制系統可用的資源。因此在乙個程序中執行...

《 Ne框架程式設計》隨記 3

以往,每個應用程式程序都有自己的虛擬位址空間,通過位址空間的隔離來保證乙個程序不會干擾另乙個程序的執行。但通過驗證託管 可以確保不會訪問不該訪問的記憶體,因此可以乙個單獨的虛擬位址空間內執行多個託管應用程式。由於太多的程序會占用過多的系統資源,損傷系統效能,並限制系統可用的資源。因此在乙個程序中執行...