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