如何通过运行时已知键获取ExpandoObject的值(CsvHelper场景)
问题解决:从CsvHelper动态对象中按运行时获取的键名取值
当使用CsvHelper读取CSV并返回dynamic类型记录时,这些记录本质是ExpandoObject,而它实现了IDictionary<string, object>接口。利用这一点,就能通过运行时获取的键名动态提取对应值,替代硬编码的属性访问(比如one.LastName)。
具体实现方法
- 将动态对象转换为字典接口:把
dynamic类型的记录转为IDictionary<string, object>,这样就能使用字典的索引器或方法来取值。 - 通过键名动态取值:
- 如果确定键名一定存在,直接用字典索引器访问;
- 如果要避免键不存在引发的异常,使用
TryGetValue方法做安全校验。
修改后的代码示例
List<string> targetColumns = new List<string>(); targetColumns.Add("LastName"); using(var streamReader = new StreamReader(@"C:\csvtesting\myfile.csv")) { using(var csvReader = new CsvReader(streamReader, CultureInfo.InvariantCulture)) { var records = csvReader.GetRecords<dynamic>().ToList(); if (!records.Any()) return; var firstRecord = records.First(); // 将dynamic转为字典接口 var recordDict = firstRecord as IDictionary<string, object>; // 方式1:直接索引(键存在时可用) if (recordDict.ContainsKey(targetColumns[0])) { var value1 = recordDict[targetColumns[0]]; // 处理value1 } // 方式2:安全取值(推荐,避免键不存在报错) if (recordDict.TryGetValue(targetColumns[0], out var value2)) { // 处理value2 } } }
为什么之前的尝试失败?
- 直接调用
one.Where(...):dynamic类型不会自动暴露LINQ扩展方法,必须先转为明确的集合类型(比如字典)才能使用这类方法。 one.list[0]:语法错误,不能直接在动态对象上用变量作为属性名,必须通过字典的索引器来实现动态访问。
内容的提问来源于stack exchange,提问作者UnskilledCoder
相关产品推荐
相关产品推荐

