所有对象存活,运作的平台就是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++) 这种方式去执行上面那段程序,结果有会不一样。
【编辑推荐】