将List(Of ExpandoObject)转为ListItem列表时遇成员不存在错误的解决办法
解决ExpandoObject转ListItem列表的成员访问错误
报错的原因是ExpandoObject是动态类型,VB.NET静态编译时无法识别它的Id/Name/Value成员——它本质是实现了IDictionary(Of String, Object)的动态对象,不能直接通过点语法访问属性,下面是几种可行的解决方法:
方法1:使用动态类型访问
将ExpandoObject声明为Dynamic,让VB.NET在运行时解析属性。注意需要确保项目的Option Strict设置为Off(可以在项目属性里调整,或在代码文件顶部添加Option Strict Off):
Option Strict Off ' 转换代码 Dim li As List(Of ListItem) = items.Select(Function(itm As Dynamic) New ListItem(itm.Id, itm.Name, itm.Value)).ToList()
这种写法最简洁,但缺点是编译时不会做类型检查,如果ExpandoObject里缺少对应键,运行时会报错。
方法2:将ExpandoObject当作字典访问
利用ExpandoObject实现IDictionary(Of String, Object)的特性,通过键名直接取值,这种方式不需要修改Option Strict,更安全:
Dim li As List(Of ListItem) = items.Select(Function(itm As ExpandoObject) Dim itemDict = DirectCast(itm, IDictionary(Of String, Object)) ' 直接取值(如果确定键一定存在) New ListItem( itemDict("Id"), itemDict("Name"), itemDict("Value") ) ).ToList()
如果担心键不存在导致报错,可以添加存在性判断:
Dim li As List(Of ListItem) = items.Select(Function(itm As ExpandoObject) Dim itemDict = DirectCast(itm, IDictionary(Of String, Object)) Dim id = If(itemDict.ContainsKey("Id"), itemDict("Id"), Nothing) Dim name = If(itemDict.ContainsKey("Name"), itemDict("Name"), Nothing) Dim value = If(itemDict.ContainsKey("Value"), itemDict("Value"), Nothing) New ListItem(id, name, value) ).ToList()
方法3:转为强类型对象(适合结构固定的场景)
如果所有ExpandoObject的结构都是固定的(都包含Id/Name/Value),可以先定义一个强类型类,再转换后使用,代码可读性和可维护性更好:
' 定义强类型类(根据实际类型调整属性类型,比如Id用Integer) Public Class ItemModel Public Property Id As Object Public Property Name As Object Public Property Value As Object End Class ' 转换代码 Dim li As List(Of ListItem) = items.Select(Function(itm As ExpandoObject) Dim itemDict = DirectCast(itm, IDictionary(Of String, Object)) Dim model = New ItemModel() If itemDict.ContainsKey("Id") Then model.Id = itemDict("Id") If itemDict.ContainsKey("Name") Then model.Name = itemDict("Name") If itemDict.ContainsKey("Value") Then model.Value = itemDict("Value") New ListItem(model.Id, model.Name, model.Value) ).ToList()
内容的提问来源于stack exchange,提问作者Oghenero E.
相关产品推荐
相关产品推荐

