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

如何将DTO记录属性存储为uint但呈现为DateTime?

问题修复与解决方案

首先指出你代码中的两个核心问题:

  1. Getter逻辑存在无限递归:get => created != null中的created是属性自身,会不断调用getter导致栈溢出,应改为判断私有字段_created。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 00:38:20