C#报错Dictionary<object,object>.KeyCollection无ToList定义如何解决
错误原因
你代码里的entryDict是Dictionary<dynamic, dynamic>类型,当你访问entryDict.Keys时,因为泛型参数是dynamic,运行时会把它当成动态对象处理,C#的动态绑定不支持识别Linq的扩展方法ToList(),所以抛出了找不到方法的异常。
修复方案
两种修复方式按需选择即可:
方式1:调整遍历逻辑,避开扩展方法调用
你原本的索引遍历完全可以替换为更简洁的foreach遍历,不需要调用ToList(),修改对应代码块即可:
foreach (var key in entryDict.Keys) { Console.WriteLine(key.ToString()); }
如果一定要保留索引遍历的写法,可以用集合构造方法转列表,避开Linq扩展方法:
String key = new List<dynamic>(entryDict.Keys)[k].ToString();
方式2:替换动态类型为明确类型,从根源解决问题
你的JSON里所有键都是字符串类型,完全不需要用dynamic作为字典的键类型,修改字典转换代码即可:
var entryDict = tableEntries[0].ToObject<Dictionary<string, object>>();
修改后entryDict.Keys就是明确的字符串键集合,可以正常调用ToList()方法,原有代码不需要其他修改即可运行。
代码优化建议
- 尽量避免滥用
dynamic类型,C#是强类型语言,能用确定类型的场景就用确定类型,既能提前发现类型错误,也能获得IDE的智能提示。如果JSON结构固定,推荐定义对应实体类做反序列化,比用动态类型或者字典更易维护。 - 遍历字典的键不需要用索引循环,直接用
foreach遍历Keys集合即可,代码更简洁可读性更高。 - 如果只是要读取JObject里的内容,不需要转成字典,直接用JObject的索引访问更方便,不需要做多余的类型转换。
优化后的完整可运行代码
using System; using Newtonsoft.Json.Linq; namespace DemoTests { class Program { static void Main(string[] args) { string jsonString = "{\"Name\":\"Bob Smith\",\"mainTitle\":\"Title1\",\"emailList\":[\"test.e@example.com\"],\"rowCount\":\"4\",\"emailSubject\":\"Test Email\",\"items\":{\"sheets\":[[{\"ID\": \"4564342\", \"start\": \"08:00\"}]]}}"; JObject jsonObj = JObject.Parse(jsonString); // 直接用JObject访问,不需要多余转字典操作 JArray sheets = jsonObj["items"]["sheets"] as JArray; foreach (var tableEntries in sheets) { JObject entry = tableEntries[0] as JObject; foreach (var property in entry.Properties()) { Console.WriteLine(property.Name); // 输出键 // Console.WriteLine(property.Value); 如需取值直接访问Value属性即可 } } } } }
内容的提问来源于stack exchange,提问作者West
相关产品推荐
相关产品推荐

