如何将定义为基类的变量保存为 json?

Posted

技术标签:

【中文标题】如何将定义为基类的变量保存为 json?【英文标题】:How can I save as json that variable defined as base class? 【发布时间】:2021-05-13 22:55:33 【问题描述】:

我正在寻找如何将定义为基类的变量保存到 json。

[Serializable]
class DataFile

    public Node root;

    public void Save()
    
        ParentNode root = new ParentNode();
        root.m_Childs = new Node[2]();
        root.m_Name = "Root";
        ParentNode node0 = new ParentNode();
        ParentNode node1 = new ParentNode();
        node0.m_Name = "Node0";
        node1.m_Name = "Node1";
        root.m_Childs[0] = node0;
        root.m_Childs[1] = node1;

        JSonUtility.ToJson(this);
    


[Serializable]
class Node

    public string m_Name;


[Serializable]
class ParentNode : Node

    public Node[] m_Childs;

使用上述代码生成的JsonUtility 仅存储rootm_Namem_Childs 不存储。

我怎么知道?

【问题讨论】:

你知道你可以EDIT你的问题并在那里添加如此重要的信息吗? ;) 在 C# 中,请使用 PascalCase 命名公共事物,例如:public Node Root;_camelCaseLeadingUnderscore 命名私有事物,例如:private Node _root; - 这也将帮助您避免基本错误,例如一个名为 root 的类级别变量和一个也称为 root: ParentNode root = new ParentNode(); 的本地级别变量,但不知道您指的是哪个。您已经付出了巨大的努力来填充一个变量,但您却因为从未真正使用过它而将其丢弃。 【参考方案1】:

当您序列化时,您正在序列化的值

public Node root;

只有一个

public string m_Name;

不是局部变量

ParentNode root = new ParentNode();

此外,(反)序列化器将使用您给它的类型,而不是它可能通过继承的类型。 DataFile 已知的唯一类型是 Node,因此它只会序列化该类型已知的字段。 ParentNode 知道的唯一类型是 Node 类型的子代。如果您需要存储 ParentNode 中包含的信息,那么您将不得不使用该类型的字段!


我想应该是这样

[Serializable]
class DataFile

    public ParentNode root;

    public void Save()
    
        var node0 = new ParentNode
            m_Name = "Node0"
        ;

        var node1 = new ParentNode
            m_Name = "Node1"
        ;

        root = new ParentNode
            m_Name = "Root",
            m_Childs = new[]node0, node1
        ;

        JSonUtility.ToJson(this);
    


[Serializable]
class Node

    public string m_Name;


[Serializable]
class ParentNode : Node

    // Again the only type known to ParentNode is childs of type Node
    // if you need ParentNode then the type has to be that also in the 
    // ParentNode class
    public ParentNode[] m_Childs;

【讨论】:

那我想接收各种继承Node作为Node[]的类,有什么办法吗?我必须将类型调整为原始类型吗?【参考方案2】:

与其他 json 库一样,Unity 默认提供的 Json Utility 在从 json 加载时无法确定存储的内容类型。我决定使用scriptable object,但是如果你真的想使用Json Utility,你可以使用ISerializationCallbackReceiver在Json序列化前后进行命令。

【讨论】:

以上是关于如何将定义为基类的变量保存为 json?的主要内容,如果未能解决你的问题,请参考以下文章

无法将参数 1 从派生指针转换为基类指针引用

将子类转换为基类?

C#通过反射将派生类转换为基类异常

通过将对象显式存储为基类来抑制虚拟机制? [复制]

如何将此“命令处理程序映射”从派生类重构为基类?

类型兼容规则