如何解析 JSON 以获取从 Newtonsoft.Json 扩展 JObject 的 class 的类型化实例?
How to parse a JSON to get a typed instance of a class that extends JObject from Newtonsoft.Json?
我想使用继承从下载的库 (Newtonsoft json) 扩展 class。也许这不是最好的解决方案,但我想了解我错过了什么。
所以,这里是基本的概述 class 我想用额外的方法进行扩展:
https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm
我创建了一个新的class,从基础class继承并实现构造函数:
public class JObjectTotalJiraTickets : JObject
{
public JObjectTotalJiraTickets(string json) : base(json) { }
public JObjectTotalJiraTickets(Object o) : base(o) { }
public JObjectTotalJiraTickets(Object[] o) : base(o) { }
public JObjectTotalJiraTickets(JObject jo) : base(jo) { }
public void sayhello()
{
Console.WriteLine("Hello!");
}
接下来,我创建新的 class 我的“自定义”实例 class:
// Here I get error CS0266 (Cannot implicitly convert type 'Newtonsoft.json.linq.JObject' to 'JObjectTotalJiraTickets)
// And propose IDE0002 (Name can be simplified), with the solution to change my type just to JObject class.
JObjectTotalJiraTickets o = JObjectTotalJiraTickets.Parse(json);
我误会了什么?使用 classes 我创建并完全控制 - 一切正常,但使用这个 - 它没有。
是的,我知道我可以像这样按类型投射,它会起作用
JObjectTotalJiraTickets o = (JObjectTotalJiraTickets)JObjectTotalJiraTickets.Parse(json);
但是为什么?为什么我不能在没有隐式转换的情况下继续?
演员表不起作用的原因是 Parse()
return 是 JObject
。即使 Parse()
在名为 JObjectTotalJiraTickets
的专门 JObject
上可用,这并不意味着它会突然 return 一个 JObjectTotalJiraTickets
而不是 JObject
.
可能的修复
您可以创建一个新的 Parse()
方法来替换原来的方法,如下所示:
public class JObjectTotalJiraTickets : JObject
{
public static new JObjectTotalJiraTickets Parse(string json)
{
// Re-use base class parse logic.
var jobj = JObject.Parse(json);
// Your logic to create a `JObjectTotalJiraTickets` from a `JObject`.
JObjectTotalJiraTickets myjobj = DoTheJiraThings(jobj)
return myjobj;
}
}
请注意替换继承的 Parse()
方法的 new
修饰符。
事实上,如果您查看 JObject
的源代码,您会发现它的确如此 exactly that to replace/extend the parse logic it inherited from JToken
。
避免继承
请注意,继承几乎总是 the worst way to go。尽可能避免它并寻找不同的方法。
“但仍然...为什么转换不起作用?”
编译器试图告诉您假设每个 JObject
也总是一个 JObjectTotalJiraTickets
是没有意义的。这就像说每个 Animal
总是一个 Cat
。这不仅是假的,而且还冒犯了猫。
然而,反过来说是有道理的:JObject o = new JObjectTotalJiraTickets()
这就像说每个 Cat
是一个 Animal
.
通过显式转换 JObjectTotalJiraTickets o = (JObjectTotalJiraTickets)new JObject()
,您实际上是在告诉编译器您知道得更多,并且您 100% 确定 JObject
实例实际上是一个 JObjectTotalJiraTickets
。编译器会相信你,但转换会在运行时失败。
我想使用继承从下载的库 (Newtonsoft json) 扩展 class。也许这不是最好的解决方案,但我想了解我错过了什么。
所以,这里是基本的概述 class 我想用额外的方法进行扩展: https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm
我创建了一个新的class,从基础class继承并实现构造函数:
public class JObjectTotalJiraTickets : JObject
{
public JObjectTotalJiraTickets(string json) : base(json) { }
public JObjectTotalJiraTickets(Object o) : base(o) { }
public JObjectTotalJiraTickets(Object[] o) : base(o) { }
public JObjectTotalJiraTickets(JObject jo) : base(jo) { }
public void sayhello()
{
Console.WriteLine("Hello!");
}
接下来,我创建新的 class 我的“自定义”实例 class:
// Here I get error CS0266 (Cannot implicitly convert type 'Newtonsoft.json.linq.JObject' to 'JObjectTotalJiraTickets)
// And propose IDE0002 (Name can be simplified), with the solution to change my type just to JObject class.
JObjectTotalJiraTickets o = JObjectTotalJiraTickets.Parse(json);
我误会了什么?使用 classes 我创建并完全控制 - 一切正常,但使用这个 - 它没有。
是的,我知道我可以像这样按类型投射,它会起作用
JObjectTotalJiraTickets o = (JObjectTotalJiraTickets)JObjectTotalJiraTickets.Parse(json);
但是为什么?为什么我不能在没有隐式转换的情况下继续?
演员表不起作用的原因是 Parse()
return 是 JObject
。即使 Parse()
在名为 JObjectTotalJiraTickets
的专门 JObject
上可用,这并不意味着它会突然 return 一个 JObjectTotalJiraTickets
而不是 JObject
.
可能的修复
您可以创建一个新的 Parse()
方法来替换原来的方法,如下所示:
public class JObjectTotalJiraTickets : JObject
{
public static new JObjectTotalJiraTickets Parse(string json)
{
// Re-use base class parse logic.
var jobj = JObject.Parse(json);
// Your logic to create a `JObjectTotalJiraTickets` from a `JObject`.
JObjectTotalJiraTickets myjobj = DoTheJiraThings(jobj)
return myjobj;
}
}
请注意替换继承的 Parse()
方法的 new
修饰符。
事实上,如果您查看 JObject
的源代码,您会发现它的确如此 exactly that to replace/extend the parse logic it inherited from JToken
。
避免继承
请注意,继承几乎总是 the worst way to go。尽可能避免它并寻找不同的方法。
“但仍然...为什么转换不起作用?”
编译器试图告诉您假设每个 JObject
也总是一个 JObjectTotalJiraTickets
是没有意义的。这就像说每个 Animal
总是一个 Cat
。这不仅是假的,而且还冒犯了猫。
然而,反过来说是有道理的:JObject o = new JObjectTotalJiraTickets()
这就像说每个 Cat
是一个 Animal
.
通过显式转换 JObjectTotalJiraTickets o = (JObjectTotalJiraTickets)new JObject()
,您实际上是在告诉编译器您知道得更多,并且您 100% 确定 JObject
实例实际上是一个 JObjectTotalJiraTickets
。编译器会相信你,但转换会在运行时失败。