為什麼值型別不允許顯式定義無參建構函式

2022-01-12 00:59:57 字數 850 閱讀 7795

在看《clr via c# 》這本書時,作者在談到值型別的例項構造器時,說到值型別不能顯式定義無參建構函式,那麼問題來了,c#編譯器為什麼阻止這麼做呢?

當程式以無參的形式new乙個struct值型別時,分配一片記憶體(注意該片記憶體是之前已經分配過的)並將這片記憶體的髒資料(因之前已經儲存了一些資料)清除掉,即zeroed,這個工作是由clr通過呼叫il形式的initobj指令完成的。當用new操作符以無參形式構造乙個struct時,new操作符被編譯為initobj。

事實上,clr允許struct值型別顯式定義無參構造器,但c#編譯器不允許。考慮下面的例子:

structfoo =newstruct[1000];

對於上面的語句,clr能夠通過分配記憶體並zeroed化記憶體的方式高效完成。如果我們顯式定義乙個無參建構函式,那麼就意味著在執行上述語句時必須呼叫struct的無引數建構函式1000次,這是極其低效率的。

事實上,c#為了讓struct和class的在例項構造這個行為上更加趨於一致,本可以允許struct值型別定義無參建構函式,但它必須保證該建構函式在類似上面的場景中不被反覆呼叫從而導致低效率。個人認為顯式定義的無參建構函式在一些場景被呼叫,而在另一些場景下不被呼叫,這破壞了一致性,同時令人困惑。因此,c#編譯器乾脆直接禁止顯式定義無參建構函式。

在c#6.0的乙個早期發行版本中,為了保持struct和class的一致性,微軟確實放開了對struct值型別不能定義無參建構函式的限制,但是經過一段時間的測試和驗證,發現這會導致一些奇怪的行為,因此,又重新恢復了之前的限制,即:不允許為struct值型別顯式定義無參建構函式。

1、2、

HashSet中為什麼不允許放重複的值

主要是因為hahcode hashcode 方法的作用 雜湊演算法,將集合分成若干個區域,每個物件在放入集合之前由計算 機計算出乙個哈吸碼,可以將雜湊碼分組,每組分別對應某個區域,根據乙個物件的雜湊碼可以 確定該物件應儲存在哪個區域。當再次向雜湊表中存入物件的時候,依舊這樣兒運算,但可以快 速的判斷...

為什麼虛構函式不允許丟擲異常

第乙個原因 session session session session 設想如果在析構函式的logdestruction函式中丟擲異常,那麼 endtransaction就不會被呼叫,因為異常發生之後異常點 即logdestruction 之後的語句塊不會被執行。因此會產生資源洩漏。解決方法如下...

MySQLtext型別不允許有預設值

mysql error 1101 text型別不允許有預設值 根據 mysql5.0以上版本 strict mode strict trans tables 的限制 不支援對not null欄位插入null值 不支援對自增長字段插入 值,可插入null值 不支援 text 欄位有預設值 在my.in...