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

求助:导出含嵌套结构体的RecordSample集合至CSV丢失属性

解决CsvHelper导出CSV时未包含object类型结构体属性的问题

问题原因

你遇到的核心问题是:CsvHelper序列化RecordSample类时,data属性的类型是object,它无法自动识别这个object实际对应的具体结构体(如EulerAnglesMessage或QuaternionMessage),因此只会导出record_time_ms、record_id这两个明确类型的属性,而忽略data内部的结构体属性。

解决方案

由于同个字典键下的data类型一致,我们可以通过反射或泛型的方式,手动展开data的属性并写入CSV。以下是两种可行的实现方式:

方式一:反射动态处理任意结构体类型

这种方式无需提前枚举所有可能的结构体类型,通用性更强:

private static void ExportRecordedData()
{
    foreach (var kvp in _recordedData)
    {
        string key = kvp.Key;
        var samples = kvp.Value;
        if (samples.Count == 0) continue;

        string path = $"{export_path}\\{key}.csv";
        using (var writer = new StreamWriter(path))
        using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            // 获取当前键下data的实际类型
            Type dataType = samples[0].data.GetType();

            // 写入表头:先写RecordSample的属性,再写data结构体的属性
            csv.WriteField("record_time_ms");
            csv.WriteField("record_id");
            foreach (var prop in dataType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                csv.WriteField(prop.Name);
            }
            csv.NextRecord();

            // 遍历每个样本,写入完整数据
            foreach (var sample in samples)
            {
                csv.WriteField(sample.record_time_ms);
                csv.WriteField(sample.record_id);
                foreach (var prop in dataType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                {
                    csv.WriteField(prop.GetValue(sample.data));
                }
                csv.NextRecord();
            }
        }
    }
}

方式二:泛型方法实现类型安全导出

如果已知所有可能的结构体类型,这种方式更具类型安全性:

// 泛型导出方法,处理特定类型的data
private static void ExportSamples<T>(List<RecordSample> samples, string path)
{
    using (var writer = new StreamWriter(path))
    using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
    {
        // 写入表头
        csv.WriteField("record_time_ms");
        csv.WriteField("record_id");
        foreach (var prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            csv.WriteField(prop.Name);
        }
        csv.NextRecord();

        // 写入每条数据
        foreach (var sample in samples)
        {
            var typedData = (T)sample.data;
            csv.WriteField(sample.record_time_ms);
            csv.WriteField(sample.record_id);
            foreach (var prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                csv.WriteField(prop.GetValue(typedData));
            }
            csv.NextRecord();
        }
    }
}

// 主导出方法
private static void ExportRecordedData()
{
    foreach (var kvp in _recordedData)
    {
        string key = kvp.Key;
        var samples = kvp.Value;
        if (samples.Count == 0) continue;

        string path = $"{export_path}\\{key}.csv";
        Type dataType = samples[0].data.GetType();

        // 根据实际类型调用对应泛型方法
        if (dataType == typeof(EulerAnglesMessage))
        {
            ExportSamples<EulerAnglesMessage>(samples, path);
        }
        else if (dataType == typeof(QuaternionMessage))
        {
            ExportSamples<QuaternionMessage>(samples, path);
        }
        // 新增结构体类型时,在此添加分支即可
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 04:25:56