You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DispatcherTimer修改Interval后,原TimeSpan对象的去向及new关键字疑问

嘿,这个问题问得很细致,我来给你把这个逻辑掰扯明白~

先把你的代码贴出来方便对照:

DispatcherTimer dt = new DispatcherTimer();
dt.Interval = new TimeSpan(0, 0, 0, 0, 100);
dt.Tick += new EventHandler(dt_dt);
// 后续修改间隔
dt.Interval = new TimeSpan(0, 0, 0, 0, 50);
第一个TimeSpan对象的去向

首先要明确:TimeSpan是值类型(结构体),不是引用类型,这是理解这个问题的核心。

当你第一次执行dt.Interval = new TimeSpan(0, 0, 0, 0, 100);时,new TimeSpan(...)创建了一个100毫秒的TimeSpan值类型实例,这个值会被完整复制到dt.Interval属性的存储位置里。

当你后续赋值新的TimeSpan时,新的50毫秒值会直接覆盖dt.Interval里存储的旧值。这时候原来的100毫秒TimeSpan:

  • 如果你没有把它保存到其他变量里(比如没写var oldInterval = dt.Interval;),那它就没有任何地方再持有它了,系统会自动清理掉它占用的内存(值类型的内存管理很直接,栈上的实例超出作用域就会释放,堆上的则随所属对象一起被GC回收)。
  • 注意:它不是被“覆盖”了对象本身,而是不再被任何地方引用/使用,所以会被清理。而且TimeSpan是不可变的,你根本没法修改一个已存在的TimeSpan实例的数值,每个TimeSpan实例的数值都是固定的。
修改Interval时为什么要用new?

还是因为TimeSpan的不可变性——它的所有数值属性(比如Milliseconds、Seconds)都是只读的,你没法直接修改一个已有的TimeSpan实例的数值。比如你不能这么写:

// 编译错误!Milliseconds是只读属性
dt.Interval.Milliseconds = 50;

所以如果要改变dt.Interval的间隔,你必须创建一个新的TimeSpan实例(不管是用new TimeSpan(...),还是用TimeSpan.FromMilliseconds(50)这种静态方法,本质都是生成新的实例),然后把这个新实例的值赋值给Interval属性。

总结一下:旧的TimeSpan不会被“覆盖”对象本身,而是失去所有引用后被回收;修改Interval必须用new是因为TimeSpan不可变,只能通过新实例来替换旧值。

内容的提问来源于stack exchange,提问作者Raiho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:15:12