问题描述
我想使用继承从下载的库(Newtonsoft json)中扩展类。也许这不是最好的解决方案,但我想了解我错过了什么。
所以,这里是我想用附加方法扩展的基本类的概述: https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm
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!");
}
// 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);
我误解了什么?使用我创建并完全控制的类 - 一切正常,但使用这个类 - 它没有。
是的,我知道我可以按类型进行转换,它会起作用
JObjectTotalJiraTickets o = (JObjectTotalJiraTickets)JObjectTotalJiraTickets.Parse(json);
但是什么原因呢?为什么我不能在没有隐式转换的情况下继续?
解决方法
强制转换不起作用的原因是因为 Parse()
返回一个 JObject
。尽管 Parse()
在名为 JObject
的专用 JObjectTotalJiraTickets
上可用,但这并不意味着它会突然返回 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;
}
}
注意替换继承的 new
方法的 Parse()
修饰符。
事实上,如果你查看JObject
的来源,你会发现它做了exactly that来替换/扩展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
。编译器会相信你,但转换会在运行时失败。