.NET真的不用管內存嗎?從List﹤T﹥列表聊起
所有對象存活,運作的平臺就是CLR(Common language runtime),這句話我琢磨了很久,加上最近自己寫的代碼中出現的一些有趣的現象,讓我對.net有了一些有趣的想法。拿來和大家分享下,以證謬誤,求得真知。好,閑話不說了。先拿出自己碰到寫程序時碰到的一個小插曲。和大家聊聊。
先聊一下List< T>
MSDN上的解釋Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists.
我的理解:List< T>存儲具有相同數據信息類型的列表,這個對象提供對這個列表的增刪改查的功能接口。
請大家看一下我碰到的一個對List< T>操作時碰到的有趣的問題,我把它貼出來,我想看到這篇文章的人有很多已經碰到過這個問題:
稍作說明:Error1 編譯錯誤,Error2 ,Error3 運行錯誤。話說回來,這個編譯器還是很強大的。至于為什么第一個是編譯錯誤,第二,三是運行時錯誤,我覺得這也是一個有趣的問題,如果那個大蝦還是小蝦有見解的話,叫上我一起討論下。在語義分析階段,不能發現第二個和第三個錯誤嗎?
我們先不管軟硬件問題,先看邏輯分析:
List< T> 列表的意義,和我們去超市買東西都會拿到這個東西,里面有時間,日期,價格,商品,等等,每一個信息類型基本都是一樣的。記錄我們的購買信息,我們假設拿到了這個列表,我們從第一行遍歷看起,第一個,第二個,第三個。。。。。。第n個。突然興奮的發現。超市的機器發生了錯誤。把原本1.00元的產品,讀成了0.01元。我的天!走狗屎運啦。我們興奮的拿筆自己修改這個選項。回家可以興奮的向你女朋友邀功。今天省了0.9毛哦。
我們看這個過程,遍歷,修改其中的一項。邏輯上成立嗎?一點問題都沒有,信息傳輸正確嗎?當然。我們記錄了我們修改的信息。這次我們對信息的修改完全正確無誤。并用遍歷,修改的邏輯完成了一次完美的操作。
那為什么把這個工作交給.net,它就干不了?
以下分析純粹是個人理解,沒有經過事實的佐證。如果那位有正解,在對本人想法嗤之以鼻的同時,萬望貼出自己的想法。
我想從機器讀我們寫的上面的高級指令開始分析。
編譯它,形成IL代碼,這個IL 其中,蘊含了什么信息。此次,限于本人時間和水平有限,請那位說明一下 。如果讀到此貼的大蝦。寫過了解C#編譯有什么特點,請貼出,本人除了知道語法,詞法,語意原理,大概是什么流程結構外。沒有動手實踐過,所以此步完全靠原理分析。略過
中間IL
最后的執行猜測
內存中數據與指令的猜測。
稍作說明:左邊為數據堆棧就是List< T>,右邊為對數據進行操作的指令就是add(),delete(),move()....最后形成的指令集合。下面單獨拿出一個塊獲取數據堆狀態,這個圖是一個數據邏輯圖,我自己猜測的。不是匯編指令形成的物理結構圖。不討論尋址,指針級別的內容。
回到最初,為什么?foreach()之中不可以delete,remove,modify
返回頭我們想想,如果它支持在foreach的時候改,增,刪 的話又要做些什么工作呢?
比如要刪一個。
程序大概要做幾件事情:第一 :記錄數據堆刪之前的狀態,第二做數據處理,copy歷史記錄,第三:執行操作,第四:將新的數據堆返回給原地址或壓根就改個讀的首地址得了。如果,其它對象引用了這堆數據操作就更復雜啦。這幾步只是我個人的一個理解模板,如果真要深究,什么地址,算法,壓棧,出棧什么的,程序要做的事情就更多了。
回到我們發現這個問題的起點。以及OO的理解,有趣的問題就會接總而來,如果,你寫程序的時候,模擬我上面講的那個修改賬單的過程,用OO思想又怎么樣設計呢? 把人做一個對象,把賬單做一個對象?我想如果是一個非程序員,讓他或她用面向對象的思想分析一下。至少有一半的人會這么分解這個對象圖。那如果我們也這么分解。有沒有這么問題?這中間是不是少了有價值的分解。如果那樣分解的話,軟件平臺,機器能不能直接理解我們的程序意圖,支持不支持呢?
想起我上一次發的那個帖子,從設計,數學,指令,甚至從哲學上來看OO.OO 實在是一個強大又非常難控制的思想。我們是不是需要在學習了解精美的設計模式之外,去理解程序,甚至數學的本質,那樣是不是能讓我們更有效的去掌控這個平臺的威力。
另外提一下:如果用for(int index = 0; index < myList.count; index++) 這種方式去執行上面那段程序,結果有會不一樣。
【編輯推薦】