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

如何将JSON反序列化为C#自定义对象的Queue集合?

游戏歌曲JSON序列化与反序列化问题解决

问题背景

我正在为开发中的游戏将歌曲数据转换为JSON对象,当前C#歌曲结构如下:

public readonly int Id = 1;

public readonly int BPM = 120;
public readonly string Name = "Baby's";

public readonly string Artist = "Brian";

protected Song SongFile;

public Queue<NoteChart> Chart = new Queue<NoteChart>();

Chart.Enqueue(new NoteChart { gemType = 1, Key = "D", Lane = 8, beatTime = new TimeSpan(0, 0, 0, 5, 84) });

已编写部分JSON片段,但Queue<NoteChart>类型的Chart字段映射遇到困难:

{
  "Id": 1,
  "BPM": 120,
  "Name": "Baby",
  "Artist": "Brian",
  "SongFile": "Songs/Baby",
  "Chart": {
  }
}

请问如何正确编写Chart的JSON结构以实现反序列化为C#对象?是否有更优的实现方式?


解决方案

1. 正确的Chart JSON结构

Queue<T>本质是有序集合,JSON中用数组来表示最适配。结合NoteChart的属性,Chart的JSON结构应写成:

"Chart": [
  {
    "gemType": 1,
    "Key": "D",
    "Lane": 8,
    "beatTime": "00:00:05.0840000"
  }
]
  • TimeSpan类型默认会被序列化为上述格式的字符串(主流序列化库如Newtonsoft.Json、System.Text.Json都支持这种格式的反序列化)。
  • 若有多条NoteChart数据,直接在数组中追加即可。

2. 更优实现方式

(1)改用属性替代只读字段

只读字段在反序列化时可能存在赋值限制,建议将字段改为自动属性,提升序列化兼容性:

public int Id { get; set; } = 1;
public int BPM { get; set; } = 120;
public string Name { get; set; } = "Baby's";
public string Artist { get; set; } = "Brian";
// SongFile若需要序列化,建议改为public属性
public string SongFile { get; set; } = "Songs/Baby";
public Queue<NoteChart> Chart { get; set; } = new Queue<NoteChart>();

(2)使用DTO分离序列化与业务逻辑

创建专门的**数据传输对象(DTO)**来处理JSON序列化,与业务实体Song解耦,避免业务代码受序列化规则限制:

// 序列化用的DTO
public class SongDto
{
    public int Id { get; set; }
    public int BPM { get; set; }
    public string Name { get; set; }
    public string Artist { get; set; }
    public string SongFile { get; set; }
    // 用List更适配JSON数组,反序列化后再转成Queue
    public List<NoteChartDto> Chart { get; set; } = new List<NoteChartDto>();
}

public class NoteChartDto
{
    public int gemType { get; set; }
    public string Key { get; set; }
    public int Lane { get; set; }
    public TimeSpan beatTime { get; set; }
}

// 业务实体与DTO的映射
var songDto = JsonSerializer.Deserialize<SongDto>(jsonString);
var song = new Song
{
    Id = songDto.Id,
    BPM = songDto.BPM,
    // ...其他属性映射
    Chart = new Queue<NoteChart>(songDto.Chart.Select(dto => new NoteChart
    {
        gemType = dto.gemType,
        Key = dto.Key,
        Lane = dto.Lane,
        beatTime = dto.beatTime
    }))
};

(3)序列化库配置优化

  • 若使用Newtonsoft.Json,可通过配置支持字段序列化、TimeSpan处理:
    var settings = new JsonSerializerSettings
    {
        Formatting = Formatting.Indented,
        // 若仍需保留字段,开启字段序列化
        IncludeFields = true,
        // 自定义TimeSpan格式(可选)
        Converters = { new TimeSpanConverter() }
    };
    var json = JsonConvert.SerializeObject(song, settings);
    
  • 若使用System.Text.Json,需配置包含字段或使用属性:
    var options = new JsonSerializerOptions
    {
        WriteIndented = true,
        // 若使用字段,开启字段序列化
        IncludeFields = true,
        Converters = { new TimeSpanConverter() }
    };
    var json = JsonSerializer.Serialize(song, options);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 18:35:15