C#嵌套IEnumerable动态类型转自定义类报CS1977错误
2sxc动态实体嵌套映射触发CS1977错误问题
问题复现
定义如下两个自定义类:
public class mDiagnosis { public int xId {get;set;} public string xName {get;set;} public List<mICNconcepts> xFocus {get;set;} } public class mICNconcepts { public int xId {get;set;} public string xName {get;set;} }
现有dynamic类型的IEnumerable集合tDiagnosis,集合内实体的Focus字段同样是dynamic类型的IEnumerable集合。尝试将动态实体映射为上述自定义类实例时,嵌套层级的.Select(j => new mICNconcepts())逻辑触发报错,实现代码如下:
var tDiagnosis = AsList(App.Data["Diagnosis"]); var typed = AsList(tDiagnosis) .Select(i => new mDiagnosis() { xId = i.EntityId, xName = i.Whatever, xFocus = AsList(i.Focus) .Select(j => new mICNconcepts() { xId = 1, xName = "asd" }) });
触发的错误信息:
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
实际运行中外层的.Select(i => new mDiagnosis())逻辑可正常执行,仅内层嵌套的Select触发上述错误,该问题和2sxc解析实体的特殊机制有关,涉及两层集合均为动态类型,和其他同错误码的通用场景成因不同。
问题原因
- 外层
AsList(tDiagnosis)的入参是预先赋值的变量,2sxc会将其返回值静态识别为IEnumerable<dynamic>类型,因此后续调用的Select是LINQ标准扩展方法,编译器可以正常解析lambda表达式的委托类型。 - 内层
AsList(i.Focus)的入参i.Focus是动态类型的属性,整个AsList调用属于动态分派操作,返回值会被编译器识别为dynamic类型。此时直接在动态返回值上调用Select,编译器无法确认该方法的签名,不支持直接传入未显式声明类型的lambda表达式,因此触发CS1977错误。
修复方案
最简洁的修复方式是在调用内层Select前,先将AsList(i.Focus)的结果显式转换为静态类型IEnumerable<dynamic>,将后续操作从动态分派切回静态绑定,修正后的代码如下:
var tDiagnosis = AsList(App.Data["Diagnosis"]); var typed = AsList(tDiagnosis) .Select(i => new mDiagnosis() { xId = i.EntityId, xName = i.Whatever, xFocus = ((IEnumerable<dynamic>)AsList(i.Focus)) .Select(j => new mICNconcepts() { xId = j.EntityId, // 替换为实际需要映射的字段 xName = j.Name // 替换为实际需要映射的字段 }).ToList() }).ToList();
其他可选方案:
- 不使用LINQ链式调用,单独遍历内层动态集合构造
List<mICNconcepts>实例后赋值给xFocus属性,绕开动态类型上的扩展方法调用限制。 - 给内层Select传入的lambda显式声明委托类型(例如
Func<dynamic, mICNconcepts>),但写法冗余,不推荐。
内容的提问来源于stack exchange,提问作者João Gomes
相关产品推荐
相关产品推荐

