C#类实例创建时如何为DateTimeCreated属性硬编码赋值时间戳
错误根因说明
你之前手写的属性代码会导致应用崩溃,核心原因是无限递归触发栈溢出:
- get 块里写的
Return DateTimeCreated;不是读取某个独立的存储值,是在调用这个属性自身的 get 访问器 - set 块里给
DateTimeCreated赋值,又会触发这个属性自身的 set 访问器 - 两个访问器互相来回调用,没有终止条件,栈内存瞬间耗尽,后端直接抛出致命错误,前端收到无效响应看起来就像浏览器崩溃了。
而你换成自动实现属性后值为默认时间,是因为自动属性本质是编译器帮你生成了一个默认值为空的私有存储字段,你从来没在实例初始化的时机给它赋过值,自然会显示 0001/01/01 这类默认值。
正确实现方式
你的核心需求是新实例创建的瞬间自动写入当前时间,且不允许用户手动修改这个字段,完全不需要在属性的 get/set 访问器里做逻辑,思路只需要做小幅调整,不需要推翻重来:
- 方案一(兼容性最好,所有C#版本都支持):
用独立的私有字段做实际存储,在类的构造函数(实例创建时自动执行的方法)里给时间戳赋值:// 私有存储字段,和属性分开,避免递归 private readonly DateTime _dateTimeCreated; // 只暴露get访问器,外部无法直接修改值 public DateTime DateTimeCreated { get => _dateTimeCreated; } // Item类的构造函数,new Item()的时候一定会执行 public Item() { _dateTimeCreated = DateTime.Now; } - 方案二(C# 6.0及以上版本推荐,写法更简洁):
直接用只读自动属性做初始化,连私有字段都不用自己写:
这种写法刚好适配你已经移除Create/Edit页面字段的设计:ASP.NET Core的模型绑定只会给有set访问器的属性赋值,这个只读属性从根源上就不会接收用户提交的任何值,完全符合不允许手动编辑的要求。// 只读属性,实例创建时自动初始化当前时间,外部没有set权限根本修改不了 public DateTime DateTimeCreated { get; } = DateTime.Now;
容易踩的坑提醒
千万不要把时间戳赋值逻辑写在属性的set访问器里:
- 很容易写出你之前那种递归崩掉的代码
- 触发时机完全不对:模型绑定是在实例创建完成后才会执行赋值逻辑,如果你在set里硬把值改成当前时间,等后续从数据库读取历史数据的时候,这个逻辑会直接把数据库存的真实创建时间覆盖成当前系统时间,导致业务逻辑彻底错乱。
内容的提问来源于stack exchange,提问作者BlindException
相关产品推荐
相关产品推荐

