【问题标题】:How to know the type of deserialized class??(or objects)如何知道反序列化类的类型??(或对象)
【发布时间】:2015-07-14 08:58:00
【问题描述】:

我有两节课

[Serializable]    
public class Class1
{                
    public List<String[]> items= new List<string[]>();        
}

[Serializable]
public class Class2
{
    public List<String[]> items = new List<string[]>();                
}

我序列化这些类并像这样向客户端发送数据

NetworkStream stream = client.GetStream();
MemoryStream memory = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();

Class1 data = new Class1(); // or Class2
data.items.Add(new String[]{"1", "2", "3"});       

bf.Serialize(memory, data);
memory.Position = 0;

byte[] buffer = memory.ToArray();                        

stream.Write(buffer, 0, buffer.Length);
stream.Flush();

当客户端程序从服务器接收数据时,程序会这样处理数据

BinaryFormatter bf = new BinaryFormatter();
MemoryStream memory = new MemoryStream();
NetworkStream stream = client.GetStream();

int bufferSize = client.ReceiveBufferSize;
byte[] buffer = new byte[bufferSize];
int bytes = stream.Read(buffer, 0, buffer.Length);

memory.Write(buffer, 0, buffer.Length);
memory.Position = 0;

但是在这种情况下,我不知道数据的类型是什么...是Class1???或 Class2..

如何知道反序列化类的类型??(或对象)

【问题讨论】:

    标签: c# serialization deserialization tcpclient tcp-ip


    【解决方案1】:

    你应该能够将它反序列化为一个对象,然后使用GetType()

    GetType(new BinaryFormatter().Deserialize(stream));

    【讨论】:

    • 但 GetType() 只显示 MemoryStream。我只想知道 MemoryStream 的类型有
    • 因为你还没有将它反序列化成一个对象。使用new BinaryFormatter(); 并调用Deserialize() 并将您的内存流传递给它。然后在对象上执行GetType()
    【解决方案2】:

    最好保证stream中序列化对象的类型。 也就是说,您应该定义一些顺序或协议来保证,例如,流中的第一个对象是Class1 的实例,然后是Class2 的实例。

    这样做,您可以或多或少地控制它:从流中反序列化 Class1 实例,您可以根据 Class1 对象中的数据决定流中的下一个对象。

    另一种解决方案是将Class1Class2 的对象包装到某个容器类中,然后序列化该容器的对象。 如果您每次都需要序列化相同类型的对象,它就可以了。

    但如果您只需要检查类型,则在反序列化流中的任何对象后,您可以通过is-check、比较其类型标记或通过安全转换来检查其类型。看例子:

    object d = binaryFormatter.Deserialize(stream);
    Class1 c1 = null;
    if ((c1 = d as Class1) != null) {
        //do something with c1
    }
    

    【讨论】:

    • 或者他可以只检查反序列化的对象是 Class1 还是 Class2 类型。
    • @LasseV.Karlsen,谢谢,我明白了,我会更新答案。
    • 但是是的,我完全同意你的看法,他应该尽量避免包含“未知数量和类型的对象”的序列化流。
    【解决方案3】:

    我提议将一个字节添加到从对象反序列化的字节数组的头部,在服务器中,您只需检查第一个字节即可知道该缓冲区的类。这将提高服务器性能。

    switch(buffer[0])
    {
        case DataType.NORMAL:
        ...
        break;
        case DataType.FILE_TRANSFER:
        ...
        break;
        ....
    }
    

    【讨论】:

    猜你喜欢
    • 2012-02-29
    • 1970-01-01
    • 2013-10-16
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多