C# 将序列化与语法分析相结合的方法?

C# 将序列化与语法分析相结合的方法?,c#,parsing,serialization,C#,Parsing,Serialization,我遇到了一个进退两难的局面。我的C#应用程序使用自定义文件格式,需要在文本编辑器中进行人工编辑,但也可以通过我的应用程序中的GUI进行编辑。该文件将表示一个顶级对象(称为TopObject),其中包含几个较小的对象,而这些对象又包含其他对象,依此类推。文件中提供了这些对象中包含的所有数据 如何加载/保存这些文件的问题一直困扰着我。C#序列化对我来说不起作用,因为它破坏了人类的可编辑性(二进制序列化),或者在序列化基类集合时存在“问题”(XML和DataContract序列化,在序列化基类时添加文

我遇到了一个进退两难的局面。我的C#应用程序使用自定义文件格式,需要在文本编辑器中进行人工编辑,但也可以通过我的应用程序中的GUI进行编辑。该文件将表示一个顶级对象(称为TopObject),其中包含几个较小的对象,而这些对象又包含其他对象,依此类推。文件中提供了这些对象中包含的所有数据

如何加载/保存这些文件的问题一直困扰着我。C#序列化对我来说不起作用,因为它破坏了人类的可编辑性(二进制序列化),或者在序列化基类集合时存在“问题”(XML和DataContract序列化,在序列化基类时添加文本以消除派生类的歧义,这使得文件对人类编辑更加脆弱);如果不是因为需要手动编辑这些文件,它本来就是一张罚单。我一直在研究解析器生成器,如GOLD和GPLEX/GPPG,以解析文件并将其转换为它们所表示的对象,这看起来很有希望,但这只涉及加载文件的一个方向,不能确保在写入文件时以正确的格式保存文件

最好是指定一种同时处理这两个问题的语法:
1) 读取具有指定结构的文件并将其转换为拓扑对象及其包含的所有对象,以及
2) 给定一个拓扑对象,将其状态写入具有相同结构的文件。
基本上,只有一种语法可以强制执行导入结构和输出结构


有没有这样的工具或框架可以帮助我?这是可行的,还是我想得太多了,还有更简单的方法?

我仍然会使用XML,但只需编写自己的序列化程序。您可以使用.Net中的XML reader/writer类创建简单的XML格式:

<TopObject>
    <SubObject>
        <SubObject>
            etc.
        </SubObject>  
        <SubObject>
            etc.
        </SubObject>
    </SubObject>
    <SubObject></SubObject>
</TopObject>
它调用一个名为递归序列化的方法,该方法执行实际工作:

private static void RecursivelySerialize(ref XmlWriter writer, Node sc) {
    writer.WriteStartElement("Node");

    writer.WriteElementString("SomeProperty", sc.SomeProperty);

    if (sc.Children.Count > 0) {
        writer.WriteStartElement("Nodes");

        foreach (Node scChild in sc.Children)
            RecursivelySerialize(ref writer, scChild);

        writer.WriteEndElement();
    }

    writer.WriteEndElement();
}
这个方法并不复杂。为了改进它,您可以使用反射来动态序列化任何类型的类。以下是我在运行上述代码时得到的输出(格式很好):

<?xml version="1.0" encoding="utf-8"?>
<Node>
    <SomeProperty>This is the base class</SomeProperty>
    <Nodes>
        <Node>
            <SomeProperty>This is a child</SomeProperty>
                <Nodes>
                    <Node>
                        <SomeProperty>This is a child of a child</SomeProperty>
                    </Node>
                </Nodes>
        </Node>
        <Node>
            <SomeProperty>This is another child</SomeProperty>
        </Node>
    </Nodes>
</Node>

这是基类
这是一个孩子
这是一个孩子的孩子
这是另一个孩子

就我个人而言,我不会过多地讨论让文件由人工编辑,至少非技术人员不可编辑。如果一个应用程序需要使用该文件,那么它将需要准确性,而且无论你建立什么样的语法,人类仍然会弄错


XML/JSON/INIs对于一些技术人员来说仍然很难不搞砸(令人惊讶),但至少他们对一些技术人员来说很熟悉。我认为这些都是比你自己的语法更好的选择。更好的是,如果你想使文件的编辑更加人性化,你可以考虑删除“人类编辑”的要求,使它只能由应用程序编辑。

@ SimeCooDe,你能给出一个自定义序列化器的小例子吗?
private static void RecursivelySerialize(ref XmlWriter writer, Node sc) {
    writer.WriteStartElement("Node");

    writer.WriteElementString("SomeProperty", sc.SomeProperty);

    if (sc.Children.Count > 0) {
        writer.WriteStartElement("Nodes");

        foreach (Node scChild in sc.Children)
            RecursivelySerialize(ref writer, scChild);

        writer.WriteEndElement();
    }

    writer.WriteEndElement();
}
<?xml version="1.0" encoding="utf-8"?>
<Node>
    <SomeProperty>This is the base class</SomeProperty>
    <Nodes>
        <Node>
            <SomeProperty>This is a child</SomeProperty>
                <Nodes>
                    <Node>
                        <SomeProperty>This is a child of a child</SomeProperty>
                    </Node>
                </Nodes>
        </Node>
        <Node>
            <SomeProperty>This is another child</SomeProperty>
        </Node>
    </Nodes>
</Node>