VB.NET反序列化含数组JSON失败:粘贴特殊生成类为何报错?
问题与解答:JSON粘贴为类的数组属性声明问题
问题背景
尝试反序列化以下JSON:
{ "Compensations": [ {"Name": "Compensation_01"}, {"Name": "Compensation_02"} ] }
使用Visual Studio的「粘贴特殊 => 将JSON粘贴为类」功能生成了如下VB.NET代码:
Public Class Rootobject Public Property Compensations() As Compensation End Class Public Class Compensation Public Property Name As String End Class
但无论是用Newtonsoft.Json还是System.Text.Json反序列化,都会抛出异常:
- Newtonsoft.Json:
Newtonsoft.Json.JsonSerializationException: '无法将当前JSON数组(例如 [1,2,3])反序列化为类型...' - System.Text.Json:
System.Text.Json.JsonException: 'JSON值无法转换为... Path: ... LineNumber: ... BytePositionInLine:'
查看IL代码发现,自动生成的Public Property Compensations() As Compensation并未生成数组类型:
public Compensation Compensations { get; set; }
手动修改为Public Property Compensations As Compensation()后,IL代码才显示为正确的数组类型:
public Compensation[] Compensations { get; set; }
疑问
- 为何「粘贴特殊」功能会生成这种形式的属性声明?
Compensations() As Compensation的含义是什么?
解答
1. 「粘贴特殊」生成错误声明的原因
这是Visual Studio的「JSON粘贴为类」功能处理VB.NET代码时的已知bug。该功能解析JSON数组时,错误颠倒了VB.NET的数组语法位置——把数组括号()放在了属性名称后面,而非类型后面,导致生成的代码不是数组类型,而是单个Compensation对象的属性。
2. Compensations() As Compensation的含义
在VB.NET中,这种写法不是数组属性声明,而是默认属性(Default Property)的语法。默认属性允许你像访问数组一样调用对象,比如rootobject.Compensations(index),但它本质是一个接受参数的属性,返回单个Compensation实例,而非数组。
它等价于:
Public Default Property Compensations(ByVal index As Integer) As Compensation Get ' 内部逻辑 End Get Set(ByVal value As Compensation) ' 内部逻辑 End Set End Property
这也是为什么IL代码显示它是单个Compensation类型的属性,而非数组。
内容的提问来源于stack exchange,提问作者Martin Seck
相关产品推荐
相关产品推荐

