在Dynamic方法中按MacAddress排序JArray遇CS1977错误的解决咨询
解决dynamic方法中Lambda表达式排序JSON数组的CS1977错误
问题场景
你有如下包含以太网信息的JSON数组,需要按MacAddress字段排序:
"ethernet":[ { "name":"Ethernet", "MacAddress":"24-1C-04-11-BF-41", "Status":"Up", "LinkSpeed":"100 Mbps", "MediaType":"802.3", "AdminStatus":"Up", "NetworkName":"Unidentified network", "DriverInfo":"Driver Date 2015-04-05 ", "Description":"Realtek PCIe GBE Family ", "LinkLayerAdress":"24-1C-04-11-BF-41", "GUID":"{B0D12A82-506B-4C8A-B5BD-3F8", "PortNotAuthenticated":"False", "InterfacePaused":"False", "LowPower":"False", "Disconnected":"False" }, { "name":"Ethernet 2", "MacAddress":"70-88-6B-89-C6-FC", "Status":"Up", "LinkSpeed":"100 Mbps", "MediaType":"802.3", "AdminStatus":"Up", "NetworkName":"Unidentified network", "DriverInfo":"Driver Date 2015-09-17 ", "Description":"Realtek USB GbE Family ", "LinkLayerAdress":"70-88-6B-89-C6-FC", "GUID":"{C2A0D6A5-0769-493A-BD4A-D3E", "PortNotAuthenticated":"False", "InterfacePaused":"False", "LowPower":"False", "Disconnected":"False" } ]
使用Lambda表达式编写的排序代码如下:
JArray Ethernets_sorted = new JArray(Ethernets.OrderByDescending( obj => obj["MacAddress"]));
但在声明为dynamic的方法中运行时,出现编译错误CS1977:Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type(无法在动态调度操作中使用Lambda表达式,除非先将其转换为委托或表达式树类型)。
解决方案
方法1:将dynamic对象强转为IEnumerable
通过显式转换,让编译器明确调用的是LINQ的OrderByDescending方法,从而推断Lambda的委托类型:
JArray Ethernets_sorted = new JArray(((IEnumerable<JToken>)Ethernets).OrderByDescending(obj => obj["MacAddress"].ToString()));
这里调用ToString()是为了确保获取MacAddress的字符串值,避免JToken类型的比较歧义。
方法2:显式指定Lambda的委托类型
直接将Lambda表达式转换为明确的Func<JToken, string>委托,消除动态调度的不确定性:
JArray Ethernets_sorted = new JArray(Ethernets.OrderByDescending((Func<JToken, string>)(obj => obj["MacAddress"].ToString())));
方法3:避免使用dynamic,强类型化处理JSON
如果场景允许,提前将JSON对象解析为强类型的JArray,而非dynamic,从根源避免该错误:
// 假设yourJsonString是包含ethernet数组的完整JSON字符串 JObject jsonObj = JObject.Parse(yourJsonString); JArray Ethernets = jsonObj["ethernet"] as JArray; JArray Ethernets_sorted = new JArray(Ethernets.OrderByDescending(obj => obj["MacAddress"].ToString()));
原理说明
错误的核心原因是:当调用dynamic类型对象的方法时,编译器无法在编译期推断Lambda表达式对应的委托类型,必须显式指定或通过强转让编译器明确类型信息,才能正确进行静态绑定。
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

