我有这个 json:
var x = [
[99,"abc","2dp",{"GroupNum": 0,"Total":[4, 1]}],
[7,"x","date"],
[60,"x","1dp",{"GroupNum": 1}],
...
]
存在以下规则(让i
引用内部列表索引):
x[i][0]
- 必填项 - 始终为整数x[i][1]
- 必填项 - 始终为字符串x[i][2]
- 必填项 - 始终为字符串x[i][3]
- 可选项目 - 当它存在时,它具有以下规则:x[i][3].GroupNum
- 必填字段 - 始终为整数x[i][3].Total
- 可选字段 - 如果它存在,则它是一个整数列表
所以我为这些规则创建了以下类:
public class ReportTemplateField : System.Collections.CollectionBase
{
public object this[int index]
{
get
{
switch (index)
{
case 0:
return (int)List[index];
case 1:
case 2:
return (string)List[index];
case 3:
return (ReportGrouping)List[index];
default:
throw new System.ArgumentOutOfRangeException("Class ReportTemplateField only contains 4 items");
}
}
set
{
switch (Count)
{
case 0:
List[index] = unchecked((int)value);
break;
case 1:
case 2:
List[index] = (string)value;
break;
case 3:
List[index] = (ReportGrouping)value;
break;
default:
throw new System.ArgumentOutOfRangeException("Class ReportTemplateField may only contain 4 items");
}
}
}
public void Add(object item)
{
switch (Count)
{
case 0:
List.Add(unchecked((int)item));
break;
case 1:
case 2:
List.Add((string)item);
break;
case 3:
List.Add((ReportGrouping)item);
break;
default:
throw new System.ArgumentOutOfRangeException("Class ReportTemplateField may only contain 4 items");
}
}
}
public class ReportGrouping
{
public int GroupNum { get; set; }
public List<int> Total { get; set; }
}
但是,当我尝试使用 json.net 进行反序列化时,从未使用过 ReportTemplateField
类。我知道这一点是因为我在每个方法中都设置了断点,但没有一个被触发:
string json = "[[99,\"abc\",\"2dp\",{\"GroupNum\": 0,\"Total\":[4, 1]}],[7,\"x\",\"date\"],[60,\"x\",\"1dp\",{\"GroupNum\": 1}]]";
List<ReportTemplateField> parsed = JsonConvert.DeserializeObject<List<ReportTemplateField>>(json);
int Total01 = parsed[0][3].Total[1];
给我这个错误:
error CS1061: 'object' does not contain a definition for 'Total' and no extension method 'Total' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
但是,如果我只是单独反序列化 ReportGrouping
,它会起作用:
string json2 = "{\"GroupNum\": 0,\"Total\":[4, 1]}";
ReportGrouping parsed2 = JsonConvert.DeserializeObject<ReportGrouping>(json2);
parsed2.Total[1]; // 1
所以问题出在 ReportTemplateField
类上。也许我不应该从 System.Collections.CollectionBase
继承?我基本上按照这个演练进行了一些修改 - https://msdn.microsoft.com/en-us/library/xth2y6ft(v=vs.71).aspx但它确实说文档可能已过时。我使用的是 .NET 4.5,所以请在您的任何回答中考虑到这一点。
我怎样才能让 Json.net 正确反序列化,这样我就可以 parsed[0][3].Total[1];
访问第二个总数的整数值而不用需要施放它或对它做任何事情吗?
最佳答案
代码中有一些错误,1 是对象没有名为 Total 的属性,另一个是 parsed[0][3] 是一个字符串。
代码中有一些错误:
- parsed[0][3] 是一个字符串。通过将字符串转换为 ReportGrouping 来修复它。
- new ReportGrouping().GroupName根据Json命名为Group。
在将 parsed[0][3] 解析为 ReportingGroup 后,它仍会返回一个对象,因此之后将 i 转换为 ReportingGroup。 IE。 (ReportingGroup)解析[0][3]。
get { switch (index) { case 0: return (int)List[index]; case 1: case 2: return (string)List[index]; case 3: return JsonConvert.DeserializeObject<ReportGrouping>(List[index].ToString()); default: throw new System.ArgumentOutOfRangeException("Class ReportTemplateField only contains 4 items"); } }
然后像这样使用它:
List<ReportTemplateField> parsed = JsonConvert.DeserializeObject<List<ReportTemplateField>>(json);
ReportGrouping group = (ReportGrouping)parsed[0][3];
不要忘记将 GroupName 重命名为 Group 并修复 setter。
编辑:抱歉我重复了这么多次..
关于c# - 将 JSON 反序列化为自定义列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38348405/