.NET真的不用管内存吗?从List﹤T﹥列表聊起

开发 后端
本文叙述了一下作者碰到的一个对List< T>操作时碰到的有趣的问题。整个过程逻辑上成立,信息传输也正确,但是在.NET下就是工作不了。作者的分析是,这个和内存中的数据与指令有关。

所有对象存活,运作的平台就是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>操作时碰到的有趣的问题,我把它贴出来,我想看到这篇文章的人有很多已经碰到过这个问题:

ListT操作问题 

稍作说明: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++) 这种方式去执行上面那段程序,结果有会不一样。

【编辑推荐】

  1. .NET组件中的线程辅助
  2. .NET组件和COM组件之间的相互操作
  3. C#和VB.NET类型相关知识汇总
  4. ASP.NET多附件上传和附件编辑的实现
  5. .NET组件的注册表中RuntimeVersion的作用
责任编辑:yangsai 来源: 博客园
相关推荐

2022-09-13 17:46:19

STA模式内存

2021-04-23 07:27:31

内存分配CPU

2009-10-12 10:04:53

VB.NET List

2022-05-09 14:09:23

多线程线程安全

2018-09-29 15:34:34

JavaList接口

2011-08-12 09:24:10

MozillaFirefox 7

2018-11-20 09:37:19

Java内存模型

2021-09-06 08:39:24

容器Docker镜像

2021-01-28 19:31:59

MySQL手册方法

2023-09-27 08:49:23

.Net分配对象

2023-12-15 10:11:31

数据结构方式

2020-12-29 10:12:19

WindowsLinux操作系统

2017-08-07 08:32:58

泄密网盘存储

2020-10-21 10:53:33

Google垄断法浏览器

2020-12-24 06:00:27

Python编程语言开发

2016-06-01 15:42:58

Hadoop数据管理分布式

2021-11-29 09:45:57

枚举Go代码

2019-06-14 14:48:41

多云云计算云平台

2020-03-04 10:13:55

Kubernetes容器开发

2020-04-17 14:25:22

Kubernetes应用程序软件开发
点赞
收藏

51CTO技术栈公众号