我正在编写一项服务,以便通过公司中的另一个团队通过HTTP从API检索数据。来自其API的JSON响应主体看起来像这样:
"SomeObject": {
"SomeInnerObject": {
"SomeProperty": {
"Id": "123",
"Type": "abc",
"Name": "some value"
}
}
}
我正在编写一个C#类以将数据存储在内存中,以便进行一些比较。 JSON对象的嵌套使该类看起来令人讨厌地重复:
public class MyClass
{
public SomeObjectModel SomeObject { get; set; }
public class SomeObjectModel
{
public SomeInnerObjectModel InnerObject { get; set; }
public class SomeInnerObjectModel
{
// etc...
}
}
}
我肯定知道诸如“ SomeObjectModel”之类的内部类只能从其他地方读取而不会在其他地方实例化,所以有没有办法将类定义和属性定义行组合成更类似的东西? / p>
public class MyClass
{
public SomeObject { get; set; } :
{
public SomeInnerObject { get; set; } :
{
// etc...
}
}
}
编辑:
JSON中将包含数组,因此,如果您提议使用泛型等替代方案,请考虑到这一点。
答案 0 :(得分:6)
如果仅使用此方法反序列化JSON,则甚至无需定义类。可以使用嵌套的anonymous type。
首先,创建并填充(具有虚拟值)具有您需要能够读取的属性的匿名类型。然后将其作为第二个参数传递给DeserializeAnonymousType<T>(string,T)
。
结果是您创建的具有相同匿名类型的新实例,但是现在它填充了JSON中的值。
var json = @"{'SomeObject': {'SomeInnerObject': {'SomeProperty': {'Id': '123','Type': 'abc','Name': 'some value'}}}}";
var template = new
{
SomeObject = new
{
SomeInnerObject = new
{
SomeProperty = new
{
Id = default(int),
Type = default(string),
Name = default(string)
}
}
}
};
var result = JsonConvert.DeserializeAnonymousType(json, template);
var id = result.SomeObject.SomeInnerObject.SomeProperty.Id;
var type = result.SomeObject.SomeInnerObject.SomeProperty.Type;
var name = result.SomeObject.SomeInnerObject.SomeProperty.Name;
Console.WriteLine("{0} {1} {2}", id, type, name);
输出:
123 abc some value
请参阅我的working example on DotNetFiddle。
编辑:如果JSON包含一个数组,则可以使用new[] {}
根据类型推断创建一个数组,然后将匿名类型放入其中,如下所示:
var json = @"{ 'SomeObjects': [ { 'Id': '123', 'Name': 'some value' }, { 'Id': '456', 'Name': 'another value' } ]}";
var template = new
{
SomeObjects = new [] { new { Id=default(int), Name=default(string)} }
};
答案 1 :(得分:2)
简短的回答是“否”,C#不支持该语法糖的任何版本。 C#中最接近的东西可能是匿名类型或值元组。
其他语言具有相似的功能:
以此类推。我认为第一件事是最接近您要寻找的东西。
在过去的十年中,针对C#多次提出了标量样式的类声明,并且最终可能将其纳入C#8中。参见https://blog.cdemi.io/whats-coming-in-c-8-0-records/
答案 2 :(得分:0)
您可以使用dynamic type。这是一个最小的示例:
using Newtonsoft.Json;
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
dynamic x = JsonConvert.DeserializeObject("[{key: '1001', value: 'test'}, {key: '1002', value: 'test2'}, ]");
Console.WriteLine(x[0].key);
Console.WriteLine(x[0].value);
Console.WriteLine(x[1].key);
Console.WriteLine(x[1].value);
Console.ReadLine();
}
}
}
答案 3 :(得分:0)