如何将DTO记录属性存储为uint但呈现为DateTime?
问题修复与解决方案
首先指出你代码中的两个核心问题:
- Getter逻辑存在无限递归:
get => created != null中的created是属性自身,会不断调用getter导致栈溢出,应改为判断私有字段_created。 created属性类型为DateTime?,无法直接接收uint赋值,缺少类型转换支持。
完整修复方案
1. 修复Getter递归问题
调整FoobarModel的属性getter逻辑:
public record FoobarModel { private uint? _created; public DateTime? created { // 改为判断私有字段_created,避免递归 get => _created != null ? TimeConverter.ConvertFromUnixTimestamp(_created!.Value) : null; init => _created = value != null ? TimeConverter.ConvertToUnixTimestamp(value!.Value) : null; } public FoobarModel() { } }
2. 添加隐式转换支持直接赋值uint
在TimeConverter类中添加uint与DateTime的隐式转换运算符,让uint可以直接赋值给DateTime?类型的属性:
public static class TimeConverter { public static DateTime ConvertFromUnixTimestamp(uint timestamp) => DateTime.UnixEpoch.AddSeconds((double)timestamp); public static uint? ConvertToUnixTimestamp(DateTime date) => (uint)Math.Floor((date.ToUniversalTime() - DateTime.UnixEpoch).TotalSeconds); // 新增:uint转DateTime的隐式转换 public static implicit operator DateTime(uint timestamp) => ConvertFromUnixTimestamp(timestamp); // 新增:DateTime转uint的隐式转换(可选,用于反向赋值) public static implicit operator uint(DateTime date) => ConvertToUnixTimestamp(date)!.Value; }
现在你可以直接用uint初始化属性:
var foobar = new FoobarModel() { created = (uint)1725747561 };
3. 支持JSON序列化/反序列化
针对第三方API的JSON格式(created字段为uint时间戳),自定义JSON转换器处理类型转换(以System.Text.Json为例):
public class UnixTimestampDateTimeConverter : JsonConverter<DateTime?> { public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.Null) return null; if (reader.TryGetUInt32(out uint timestamp)) return TimeConverter.ConvertFromUnixTimestamp(timestamp); throw new JsonException("无法解析Unix时间戳(秒)"); } public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options) { if (value == null) writer.WriteNullValue(); else writer.WriteNumberValue(TimeConverter.ConvertToUnixTimestamp(value.Value)!.Value); } }
在FoobarModel的属性上标记转换器:
[JsonConverter(typeof(UnixTimestampDateTimeConverter))] public DateTime? created { /* get/init逻辑不变 */ }
替代方案(无需隐式转换)
如果不想使用隐式转换,可通过构造函数或静态工厂方法实现uint初始化:
public record FoobarModel { private uint? _created; [JsonConverter(typeof(UnixTimestampDateTimeConverter))] public DateTime? created { /* get/init逻辑不变 */ } // 新增接收uint的构造函数 public FoobarModel(uint? createdTimestamp) { _created = createdTimestamp; } public FoobarModel() { } // 静态工厂方法 public static FoobarModel FromUnixTimestamp(uint timestamp) { return new FoobarModel { created = TimeConverter.ConvertFromUnixTimestamp(timestamp) }; } }
使用方式:
// 构造函数初始化 var foobar1 = new FoobarModel((uint)1725747561); // 工厂方法初始化 var foobar2 = FoobarModel.FromUnixTimestamp((uint)1725747561);
内容的提问来源于stack exchange,提问作者Escher
相关产品推荐
相关产品推荐

