关于复杂对象的序列化和反序列化

这两天被老婆骂花钱多,于是算账,可怎么怎么也算不明白了。。。哈哈。。。。平时没有记账的习惯,于是写一个小程序……实际上画蛇添足了,打开EXCEL就行了…………说说程序吧

序列化和反序列化有时也称为串行化和并行化,在VS.NET中基于对XML的支持,我们可以方便的将一个对象序列化或反序列化,这提供了很多方便。可惜,MS的示例上只有一些简单的对象的示例,对于复杂的很多朋友不知道怎么做,网上有一些C#的示例,没有VB的。

下面就来个分步讲解(别想直接看结果,嘿嘿,最终的代码没有写在这里):

构思,构思,所谓策划策划的过程,据我想啊,记账,这东西,就是不断的添加添加再添加,然后求个和了之类的事情,保存到硬盘上再读回来再……用数据库不错,可惜,从8年前学VB到现在从来不爱用,也没会用过,幸亏出现个XML,那这工作由序列化完成吧。接下来选择一个比较简单的,容易操作的,速度也不用那么快的东西ArrayList来存储信息~开工:

引入名空间:

Imports System.Xml.Serialization
Imports System.IO

构造一个记账的东西,可以构造成类,也可以用其他的东西,我就是用了下面的东西,应该说是结构,结构:

    Public Structure m_Info
        ''' <summary>
        ''' 数值
        ''' </summary>
        ''' <remarks></remarks>
        Public Value As Single
        ''' <summary>
        ''' 时间
        ''' </summary>
        ''' <remarks></remarks>
        Public Time As Date       '时间
        ''' <summary>
        ''' 原因
        ''' </summary>
        ''' <remarks></remarks>
        Public Purpose As Purpose '原因
        ''' <summary>
        ''' 人员
        ''' </summary>
        ''' <remarks></remarks>
        Public Who As Who         '人员
        ''' <summary>
        ''' 备注
        ''' </summary>
        ''' <remarks></remarks>
        Public Reason As String   '备注
        Sub Initialization()
            Me.Time = Date.Now
            Me.Value = 0
            Me.Purpose = 0
            Me.Reason = ""
            Me.Who = 0
        End Sub
    End Structure

这里你构造一个类还是实用结构,对最终的序列化没有影响,甚至都不用改序列化的代码。 

其中枚举如下:

    Public Enum Who
        老公 = 1
        老婆 = 2
        共同 = 0
    End Enum

    Public Enum Purpose
        in_其他收入 = 1
        in_股票 = 2
        in_基金 = 3
        in_奖金 = 4
        in_工资 = 5
        out_衣服 = -1
        out_吃饭 = -2
        out_路费 = -3
        out_礼品 = -4
        out_其他支出 = -5
    End Enum

    Public Enum InOrOut
        收入 = 1
        支出 = -1
    End Enum

这样,就成了(如果你看Purpose枚举别扭,那就先别扭着,想不别扭好办,看完教程自己改,对别人写的代码实行“搬来主义”永远不会让你学到技术)。

开头说,使用ARRAYLIST,这里又有一个岔路口,你可以Inherits arrarlist并overloads来实现添加、删除、查询、求和等功能,也可以dim info as new arraylist,应该是随便了,据我觉得,你认为这些帐目“就是一个”还是“应该是一个”还是“可以是一个”还是“能能够是一个”都没啥区别,当然了,我对继承的理解可能肤浅的多。我使用了这种方式:Public _Info As New ArrayList

接下来的代码中,实现了ADD,REMOVE,GETSUB函数的多个重载版本。没什么大意思的,不贴了,占地方,本文的主旨不是乱七八糟的。下面看SAVE和LOAD方法:

''' <summary>
    ''' 保存
    ''' </summary>
    ''' <remarks></remarks>
    Public Function Save(Optional ByRef ErrStr As String = "") As Boolean
        Dim Ret As Boolean = True
        Try
            Dim t() As Type = {GetType(m_Info)}
            Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList), t)

            Dim myWriter As StreamWriter = New StreamWriter("帐目.xml")
            mySerializer.Serialize(myWriter, _Info)
            myWriter.Close()
        Catch ex As Exception
            ErrStr = ex.ToString
            Ret = False
        End Try
        Return Ret
    End Function

    ''' <summary>
    ''' 读取
    ''' </summary>
    ''' <remarks></remarks>
    Public Function Load(Optional ByRef ErrStr As String = "") As Boolean
        Dim Ret As Boolean = True
        Try
            Dim t() As Type = {GetType(m_Info)}
            Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList), t)

            Dim myFileStream As FileStream = New FileStream("帐目.xml", FileMode.Open)
            _Info = CType(mySerializer.Deserialize(myFileStream), ArrayList)
            myFileStream.Close()
        Catch ex As Exception
            ErrStr = ex.ToString
            Ret = False
        End Try
        Return Ret
    End Function

这两个方法里面唯一需要注意的地方就是黑体部分:

            Dim t() As Type = {GetType(m_Info)}
            Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList), t)

往常序列化和反序列化一个简单的对象,都这样:

   Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList))

这里多了一个T实际上可能很多开始就学.NET的同志习惯于dim t as type()={……}这种形式的定义,不过学VB6多年了,习惯难改,实际上这两种方式是相同的解释方法。

关键问题就在于这个T的定义,如果没有这个T,你可以测试一下,将会得到类似于“生成XML文件出错”的错误,这个TYPE()参数就是告诉XmlSerializer如何去处理_Info这个对象,以什么作为参照,换句话说, Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList))的形式,只是让人家按照SYSTEM.TYPE存在的一些基本类型去解释对象(当然,这只是不准确的通俗的说法),而后面的TYPE数组将新的、自定义的类型加入,这里可以定义一个类,一个类型,一个枚举……或者它们之间任意个数个组合。

完事了,就说这么多。再回到前面:Purpose 枚举的定义比较让人恶心啊,么办法,想了好久才改到这么恶心的,这个Purpose 实际上是一个结构,里面含有两个枚举:OUT和INT。但是如果那样声明,这个文章恐怕就很晦涩了。到最后了,该讲的都讲了,你自己去改吧:Purpose 换成含有两个枚举值的结构,这样m_info结构将变成一个结构的嵌套,似乎更符合“复杂对象”这个标题,对SAVE和LOAD方法稍加修改,代码就可以正常运行。

说个题外话:游戏修改器以后不写了,这个方向做的已经很没意思了,以后开始专注SOCKET,今天就当休闲了,最近封装这个SOCKET又多线程又回调的,弄得斤数距半出栏更近了,打一会CS,之后ZZZZZzzzzzzzzz.....

最后祝大家在这个竞争激烈的软件业都有所成,至少都有大把的钞票赚。

把可测试的代码贴到这里:

类:

Imports System.Xml.Serialization
Imports System.IO

Public Class cls_Test

    Public Structure m_Info
        ''' <summary>
        ''' 数值
        ''' </summary>
        ''' <remarks></remarks>
        Public Value As Single
        ''' <summary>
        ''' 时间
        ''' </summary>
        ''' <remarks></remarks>
        Public Time As Date       '时间
        ''' <summary>
        ''' 原因
        ''' </summary>
        ''' <remarks></remarks>
        Public Purpose As Purpose '原因
        ''' <summary>
        ''' 人员
        ''' </summary>
        ''' <remarks></remarks>
        Public Who As Who         '人员
        ''' <summary>
        ''' 备注
        ''' </summary>
        ''' <remarks></remarks>
        Public Reason As String   '备注
        Sub Initialization()
            Me.Time = Date.Now
            Me.Value = 0
            Me.Purpose = 0
            Me.Reason = ""
            Me.Who = 0
        End Sub
    End Structure

    Public Enum Who
        老公 = 1
        老婆 = 2
        共同 = 0
    End Enum

    Public Enum Purpose
        in_其他收入 = 1
        in_股票 = 2
        in_基金 = 3
        in_奖金 = 4
        in_工资 = 5
        out_衣服 = -1
        out_吃饭 = -2
        out_路费 = -3
        out_礼品 = -4
        out_其他支出 = -5
    End Enum

    Public Enum InOrOut
        收入 = 1
        支出 = -1
    End Enum
    Public _Info As New ArrayList

    ''' <summary>
    ''' 添加
    ''' </summary>
    ''' <param name="info"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Add(ByVal info As m_Info) As Boolean
        _Info.Add(info)
    End Function

''' <summary>
    ''' 保存
    ''' </summary>
    ''' <remarks></remarks>
    Public Function Save(Optional ByRef ErrStr As String = "") As Boolean
        Dim Ret As Boolean = True
        Try
            Dim t() As Type = {GetType(m_Info)}
            Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList), t)
            Dim myWriter As StreamWriter = New StreamWriter("帐目.xml")
            mySerializer.Serialize(myWriter, _Info)
            myWriter.Close()
        Catch ex As Exception
            ErrStr = ex.ToString
            Ret = False
        End Try
        Return Ret
    End Function

    ''' <summary>
    ''' 读取
    ''' </summary>
    ''' <remarks></remarks>
    Public Function Load(Optional ByRef ErrStr As String = "") As Boolean
        Dim Ret As Boolean = True
        Try
            Dim t() As Type = {GetType(m_Info)}
            Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(ArrayList), t)
            Dim myFileStream As FileStream = New FileStream("帐目.xml", FileMode.Open)
            _Info = CType(mySerializer.Deserialize(myFileStream), ArrayList)
            myFileStream.Close()
        Catch ex As Exception
            ErrStr = ex.ToString
            Ret = False
        End Try
        Return Ret
    End Function

End Class

窗体:

Private Test As New cls_Test

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim test As New cls_Test.m_Info
        stest.Initialization()
        Test.Add(stest)
        Test.Save()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Test.Load()
        Debug.Print(CType(Test._Info(0), cls_Test.m_Info).Time)
    End Sub

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清晨曦月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值