在序列化时,我犯了什么错误?

8 浏览
0 Comments

在序列化时,我犯了什么错误?

这导致了运行时的序列化异常。这只是一个测试最佳实践的演示项目。我包含了主方法和我试图序列化的类。\n忽略:我真的不能提供更多细节了,我已经描述了问题,附上了代码,这个“请提供更多细节”的要求真是最愚蠢的事情。让我发布吧。\n

Data toSend = new Data();
toSend.Output();
///序列化
BinaryFormatter formatter = new BinaryFormatter();
Stream streamOut = File.OpenWrite("file");
formatter.Serialize(streamOut, toSend);
streamOut.Close();
Console.WriteLine("----------------------------");
///反序列化
Stream streamIn = File.OpenRead("file");
Object received = formatter.Deserialize(streamIn);
Data toReceive = (Data)received;
toReceive.Output();
class Data : ISerializable
{
    int integerData;
    string stringData;
    bool booleanData;
    int shouldnotbeserialized;
    public Data()
    {
        integerData = 1;
        stringData = "Hello";
        booleanData = true;
        shouldnotbeserialized = 55;
    }
    //用于反序列化
    public Data(SerializationInfo info, StreamingContext context)
    {
        integerData = info.GetInt32("theint");
        stringData = info.GetString("thestring");
        booleanData = info.GetBoolean("thebool");
    }
    public void Output()
    {
        Console.WriteLine(integerData);
        Console.WriteLine(stringData);
        Console.WriteLine(booleanData);
        Console.WriteLine(shouldnotbeserialized);
    }
    //实现的序列化方法
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("thestring", stringData);
        info.AddValue("theint", integerData);
        info.AddValue("thebool", booleanData);
    }
}

\n异常消息:\n

\n程序集“SerializationDemo”中的类型“SerializationDemo.Data”未标记为可序列化。\n

0
0 Comments

当序列化一个对象时,出现了一个错误。错误信息中给出了解决方法:类'SerializationDemo.Data'没有标记为可序列化的。需要使用Serializable属性来标记类。

从上下文来看,你似乎要通过网络传输对象(根据变量名toSendtoReceive推断)。你需要意识到,如果你使用的是客户端-服务器模型,服务器软件序列化并发送的对象默认情况下无法在客户端软件中反序列化。

这是因为二进制序列化的基本特性是保持类型系统的一致性。类型系统的一致性意味着在序列化过程中不会丢失类型信息。这意味着当你序列化一个对象时,不仅仅是将"对象的状态"写入数据流中,还包括类的名称和包含的程序集。即使你在将要反序列化数据的程序集中定义了类,反序列化方法也会失败(抛出异常),因为反序列化器将寻找类型而不是。为了解决这个问题,你可以在一个公共程序集(类库)中定义你的数据消息,或者通过定义一个SerializationBinder来欺骗反序列化方法,使其认为你仍然在同一个程序集中。

这比我想象的要复杂,这只是一个虚拟的测试程序,但是,是的,我的意图是通过TCP连接发送它。那么,在DLL中定义类并在服务器和客户端项目中链接它是一个好的策略吗?上下文是一个多人棋盘应用程序,我想传输棋盘实例。

我认为将消息定义在它们自己的程序集中是一个好主意,因为这样可以简化序列化过程,而且还意味着你不需要每次添加新消息时都复制粘贴类和可能的消息标识枚举到不同的程序集中。唯一的缺点是,你的应用程序将依赖于你的DLL,并且不再是独立可执行文件。

0