1

我正在尝试序列化一个类,然后将其反序列化为第二个类,以模仿未来对类结构的添加,所以我试图实现 ISerializable

Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary

<Serializable()> _
Public Class Serial
    Implements ISerializable


    Public Num1 As Integer
    Public Num2 As Integer

    Protected Sub New(ByVal Info As SerializationInfo, ByVal Context As StreamingContext)
        With Info
            Num1 = .GetInt32("Num1")
            Num2 = .GetInt32("Num2")

        End With
    End Sub

    Public Sub GetObjectData(info As System.Runtime.Serialization.SerializationInfo, context As System.Runtime.Serialization.StreamingContext) Implements System.Runtime.Serialization.ISerializable.GetObjectData

        With info
            .FullTypeName = "ObjectSerialization. Serial"
            .AddValue("Num1", Num1)
            .AddValue("Num2", Num2)
        End With
    End Sub
End Class

<Serializable()> _
Public Class Serial2
    Implements ISerializable


    Public Num1 As Integer
    Public Num2 As Integer
    Public Num3 As Integer

    Protected Sub New(ByVal Info As SerializationInfo, ByVal Context As StreamingContext)
        With Info
            Num1 = .GetInt32("Num1")
            Num2 = .GetInt32("Num2")
            Num3 = .GetInt32("Num3")
        End With
    End Sub


    Public Sub GetObjectData(info As System.Runtime.Serialization.SerializationInfo, context As System.Runtime.Serialization.StreamingContext) Implements System.Runtime.Serialization.ISerializable.GetObjectData

        With info
            .FullTypeName = "ObjectSerialization. Serial"
            .AddValue("Num1", Num1)
            .AddValue("Num2", Num2)
            .AddValue("Num3", Num3)
        End With
    End Sub
End Class

当我尝试在下面的代码中反序列化时,发生异常(无法加载类型 ObjectSerialization。反序列化所需的序列号)。有人可以指出我正确的方向。

Dim s1 As New Serial
Dim s2 As New Serial2
s1.Num1 = 99
s1.Num2 = 500

Dim fs As New FileStream("DataFile.dat", FileMode.Create)
Dim formatter As New BinaryFormatter
Try
    formatter.Serialize(fs, s1)
Catch ex As SerializationException
    Console.WriteLine("Failed to serialize. Reason: " & ex.Message)
Finally
    fs.Close()
End Try

fs = New FileStream("DataFile.dat", FileMode.Open)
Try
    formatter = New BinaryFormatter

    s2 = formatter.Deserialize(fs)
Catch ex As SerializationException

    Console.WriteLine("Failed to deserialize. Reason: " & ex.Message)
    Throw
Finally
    fs.Close()
End Try

End Sub
4

2 回答 2

1

您是否尝试过删除 ObjectSerialization 中的空间。串行并仅使用 ObjectSerialization.Serial ?

您的代码在此更改后在我的机器上运行并添加了一个公共无参数构造函数

您还可以执行以下操作:

Try
    formatter = New BinaryFormatter
    Dim tmp As Serial = formatter.Deserialize(fs)
    s2.Num1 = tmp.Num1
    s2.Num2 = tmp.Num2
Catch ex As SerializationException

    Console.WriteLine("Failed to deserialize. Reason: " & ex.Message)
    Throw
Finally
    fs.Close()
End Try

您可以使用这样的通用方法,而不是一个一个地复制属性:http: //www.codeproject.com/Articles/173664/Copy-Properties-From-One-Object-To-Another

于 2013-10-19T20:12:24.117 回答
0

我可以s1 = formatter.Deserialize(fs)正常上班。 s2 = formatter.Deserialize(fs)但是每次都失败。

Serial required for deserialization意味着您不能将对象 A 反序列化为对象 B(Serial 是关键字,指的是您的类名)。MS 二进制序列化程序要求您反序列化为序列化数据的同一类文化程序集对象。当 MS 序列化类文化程序集时,信息是二进制数据的一部分。有一些方法可以解决这个问题,例如编写序列化服务(如在 DLL 中)和其他方法,但没有直接的方法。

如果您正在寻找一种数据交换序列化程序,请查看 ProtoBuf-NET。它既比 MS 快,又产生小得多的输出(空字典从 3000 到 300 字节)。PBN 易于使用,并允许您执行帖子文本 ( de-serialize it to a second class) 所描述的操作。实际上语法几乎相同。

编辑

好的,我不确定在这种情况下“串行”指的是什么。我更改了类名并得到相同的错误,因此它可能与接口的使用有关(这似乎是一种将反序列化为不同类型对象的方法)。当我尝试在两种类型之间交换数据时,消息给了我一些类似于“myclass-english blah blah blah-myassembly”的信息,无法反序列化为“myclass2-english-blah blah blah-otherassembly”。

啊哈!

将类更改为没有 ISerializable 的非常简单的类:

Public Class fromClass


Public Num1 As Integer
Public Num2 As Integer

Public Sub New()

End Sub

End Class

公共成员的工作方式与将它们包装在属性 getter/setter 中一样(abd 没有理由这不起作用)。现在,当您尝试反序列化到 S2 时,会出现一条新消息: Unable to cast object of type 'WindowsApplication1.fromClass' to type 'WindowsApplication1.toCLass'.

ISerializable 掩盖了这个问题。你不能反序列化成别的东西。查看输出文件的文本 - 类文化程序集信息在那里(并且是您原始错误消息的来源)。我认为至少部分原因是反射用于序列化;如果它不回到同一件事,它就不会尝试(尽管它看起来像使用接口应该可以工作)。另一个原因可能是安全性。PBN 更加聪明和灵活,或多或少是围绕数据交换设计的。

于 2013-10-19T20:23:53.870 回答