这是一个古老的问题,其他语言里面几乎没有,C#、C++中有类似的概念,但思想是不同。
Pascal中的Record是复制型赋值,Class是引用复制。这个基础逻辑很关键。涉及到延伸的功能实现产生的错误。
delphi中有一个声明在Diagnostics的秒表功能,是以Record记录的方式实现的,即 TStopwatch=Record….,我希望通过这已有的功能扩展生成通用的超时功能。为此想用字典的方式增加了一个TTimeOut的(记录、类),从原理上两者都可以,实现相关逻辑。
- 每次需要增加一个判断标记,并开始一个记时,
- TTimeOut的(记录、类)内会有一个任务(线程、工作、任务),扫描存在的标记,
- 超过时间即报警,并清除标记和记录。
但实际上就发生了问题,TTimeOut 第一次声明的词典是 TDictionary<string, _TStopwatch>,但是_TStopwatch定义的是记录。在使用过程中字典中中的值始终没有变化。监视字典“表计”是否实现Start动作,均有。但到了内部isRunning却都是False。然后计划将_TStopwatch通过指针方式声明,操作过程中发现,为什么要这么麻烦。直接将_TStopwatch声明为类不就是一样的效果。带来的附带问题,就是资源释放。Delphi提供了 TObjectDictionary<string, _TStopwatch>,这样就很方便了,释放的问题也就没有了。
代码小做改动、测试OK。
总结:
记录是复制传值,所以TDictionary<string, _TStopwatch>的Item并不是原实例,而TObjectDictionary<string, _TStopwatch>的Item是参照,指向的就是原实例。
备注:
- 为什么原生语言中定义了类还要定义指针,效率是一方面,合理才是更重要的原因。
- 如前文准备用指针方式。
- Class本身就是指针。