VB与C#访问JProperty差异:C#调用asset_bundle.assets报错问题
问题产生原因
- 语言特性差异:VB默认关闭
Option Strict,支持后期绑定,运行时会自动解析object类型变量的成员,不需要编译期验证属性是否存在。而C#默认执行严格静态类型检查,编译期就会校验object类型变量调用的成员是否存在,找不到就会抛出你遇到的错误。 - 反序列化映射失败:调试显示对应对象为
JProperty,说明你在将JSON数据反序列化为C#自定义类时,嵌套的asset_bundle字段没有被正确映射到你预先定义的类实例,而是保留了Json.NET的原生JSON对象结构,item.asset_bundle实际是JObject类型而非你定义的强类型,自然找不到声明的assets属性。
解决方法
你可以根据项目场景选择以下任意一种方案:
方案1:使用dynamic模拟VB后期绑定行为
仅需要修改现有代码,不需要调整反序列化逻辑,适配性最强:
private void LoadAssetEvents(object OpenSeaData) { foreach (Assets mRoot in OpenSeaData as System.Collections.IEnumerable) { foreach (AssetEvent item in mRoot.asset_events) { if (item.asset_bundle != null) { // 转换为dynamic跳过编译期静态检查,运行时动态解析assets属性 dynamic assetBundle = item.asset_bundle; foreach (var item_single in assetBundle.assets as System.Collections.IEnumerable) { ObtainEtherScanDetails(item, item_single); } } else { ObtainEtherScanDetails(item, null); } } } }
方案2:修复反序列化逻辑,实现完整强类型映射
从根源解决问题,后续访问所有字段都不需要额外处理:
- 检查自定义类的属性定义,确保
AssetEvent类中asset_bundle字段的类型是你定义的对应强类型,而非object - 给类属性添加
[JsonProperty]特性,确保属性名和JSON返回的字段名完全匹配 - 反序列化OpenSeaData时直接指定对应的强类型作为反序列化目标,不要用
object承接反序列化结果
方案3:直接操作JObject读取assets数组
如果你不想使用dynamic,也可以手动解析Json.NET原生对象:
private void LoadAssetEvents(object OpenSeaData) { foreach (Assets mRoot in OpenSeaData as System.Collections.IEnumerable) { foreach (AssetEvent item in mRoot.asset_events) { if (item.asset_bundle != null) { var bundle = item.asset_bundle as Newtonsoft.Json.Linq.JObject; var assets = bundle.GetValue("assets") as Newtonsoft.Json.Linq.JArray; foreach (var item_single in assets) { // 可根据需要将item_single转换为你定义的Asset类实例 ObtainEtherScanDetails(item, item_single); } } else { ObtainEtherScanDetails(item, null); } } } }
内容的提问来源于stack exchange,提问作者anelBavari
相关产品推荐
相关产品推荐

