0

Reader C# 项目需要将 ~POCO 保存到文件中。但我们刚刚出道,变化经常发生。我们的软件已经被少数客户使用(坚持使用)。出于多种原因,我更喜欢使用 XML。

我检查了许多 xml 序列化库。

  • 许多库存储特定的类型和版本。我不需要那个。
  • 许多库不给我们自己序列化的可能性:即我们需要一个自定义加载/保存数据的接口(我看到很多优点**)
  • 一些库迫使我们有空的构造函数
  • 一些库只管理公共属性
  • 一些库对类型有很多限制(不支持字典,...)

**(加载/保存数据界面的优势)

  • 更容易管理多个版本
  • 如果需要,可以进行硬编码转换(x 类 -> y 类,...)
  • 更容易不保留旧代码

我强烈认为,根据我的需要,我们最好使用旧方法来服务:有点像 C++ 中的反序列化。我认为我们会更好地服务于使我们能够手动添加字段和字段名称而不是使用属性的东西。

有点儿:

void XmlDeserialize(XmlReader xmlReader)
{
  xmlReader.Load((n)=>Version(n)); // or just: _version = xmlReader.LoadInt("Version"); 
  xmlReader.Load((n)=>Name(n));
  xmlReader.Load((n)=>EmployeeId(n));

    if (Version ==2)
                    …

    If (version == 3)
                    …

我发现最能满足我的需求的是:支持 IExtensibleDataObject 的 DataContractSerializer,但使用起来很麻烦。

我问自己,我是不是到处都错了?我不可能是唯一有这种需求(或这种愿景)的人。为什么没有人为此编写任何库,而我在某个地方错过了什么?

我想错了什么?你有什么建议吗 ?

4

2 回答 2

0

你必须为此使用 XML reader.load 吗?创建代表您的 XML 数据的业务对象,然后反序列化该对象要容易得多,如下所示(抱歉,我只找到了我的 vb.net 版本):

Public Shared Function ReadFromString(ByVal theString As String, ByVal encoding As System.Text.Encoding, ByVal prohibitDTD As Boolean) As T
        Dim theReturn As T = Nothing
        Dim s As System.Xml.Serialization.XmlSerializer
        s = New System.Xml.Serialization.XmlSerializer(GetType(T))

        Dim theBytes As Byte() = encoding.GetBytes(theString)
        Using ms As New IO.MemoryStream(theBytes)
            Using sTr As New StreamReader(ms, encoding)
                Dim sttng As New XmlReaderSettings
                'sttng.ProhibitDtd = prohibitDTD
                If Not prohibitDTD Then
                    sttng.DtdProcessing = DtdProcessing.Ignore
                    sttng.XmlResolver = Nothing
                Else
                    sttng.DtdProcessing = DtdProcessing.Prohibit
                End If
                Using r As XmlReader = XmlReader.Create(sTr, sttng)
                    theReturn = CType(s.Deserialize(r), T)
                End Using
            End Using
        End Using


        Return theReturn
    End Function

如果您愿意,您可以删除 xmlreadersettings 和编码。但是通过这种方式,您可以为您拥有的每个版本保留不同的业务对象吗?此外,如果您只是添加(而不是更改/删除)对象,您仍然可以为所有版本使用最新的业务对象,而忽略缺少的字段。

于 2012-05-31T22:05:52.847 回答
0

我最终决定像这种 用法一样使用 XmlSerialization,但我讨厌被迫创建默认构造函数并且无法序列化成员(私有或公共)。

我还决定在需要非常高的速度时使用 ProtoContract。

但我更喜欢的是 DataContractSerializer,它提供 xml 格式(更易于调试),不需要默认构造函数并且可以序列化任何成员。

于 2013-12-19T19:17:34.813 回答