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

如何提取CSV每行有数据的列头?解决ExpandoObject索引报错

问题与解决方案

问题描述

需要提取CSV文件中每行存在数据的列头(示例:第一行Column B、Column D无数据,输出Column A、Column C;第二行Column C无数据,输出Column A、Column B、Column D)。使用CsvReader读取CSV到dynamic列表时触发错误:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'Cannot apply indexing with [] to an expression of type 'System.Dynamic.ExpandoObject''

原代码如下:

string csvFilePath = "your_csv_file.csv";

using (var reader = new StreamReader(csvFilePath))
using (var csv = new CsvReader(reader, new CsvConfiguration(CultureInfo.InvariantCulture)))
{
    // Read the CSV records into a dynamic list
    var records = csv.GetRecords<dynamic>().ToList();

    // Get the headers from the first record
    var headers = ((IDictionary<string, object>)records[0]).Keys.ToList();

    // Create a list to store headers with data
    var headersWithData = new List<string>();

    // Iterate through headers and check if any row in the column has data
    foreach (var header in headers)
    {
        if (records.Skip(1).Any(record => !string.IsNullOrWhiteSpace(record[header]?.ToString())))
        {
            headersWithData.Add(header);
        }
    }

    // Print the filtered column headers with data
    Console.WriteLine("Column Headers with Data:");
    foreach (var header in headersWithData)
    {
        Console.WriteLine(header);
    }
}

解决方案

错误根源是dynamic类型的ExpandoObject不支持直接用[]索引访问,需将其强制转换为IDictionary<string, object>接口后再操作。修改后的代码如下:

string csvFilePath = "your_csv_file.csv";

using (var reader = new StreamReader(csvFilePath))
using (var csv = new CsvReader(reader, new CsvConfiguration(CultureInfo.InvariantCulture)))
{
    var records = csv.GetRecords<dynamic>().ToList();
    var headers = ((IDictionary<string, object>)records[0]).Keys.ToList();
    var headersWithData = new List<string>();

    foreach (var header in headers)
    {
        // 将record强制转换为IDictionary<string, object>后再访问键值
        if (records.Skip(1).Any(record => 
            !string.IsNullOrWhiteSpace(((IDictionary<string, object>)record)[header]?.ToString())))
        {
            headersWithData.Add(header);
        }
    }

    Console.WriteLine("Column Headers with Data:");
    foreach (var header in headersWithData)
    {
        Console.WriteLine(header);
    }
}

关键修改点

在判断每行对应列是否有数据时,将record[header]替换为((IDictionary<string, object>)record)[header]——因为ExpandoObject本身实现了IDictionary<string, object>接口,强制转换后即可通过键名(列头)访问对应的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 02:27:19