简体   繁体   English

如果我不知道正确的类型,如何反序列化对象?

[英]How can I deserialize an object if I don't know the right type?

Well I want to send commands and data between client and server. 好吧,我想在客户端和服务器之间发送命令和数据。

I have three projects: 我有三个项目:

  • Client 客户
  • Server 服务器
  • Common - here I put common classes and network abstraction layer 通用-在这里我放置通用类和网络抽象层

I am using following data structures for communications between client and server 我正在使用以下数据结构进行客户端和服务器之间的通信

public class Packet<T>
{
        public string Name { get; set; }
        public string From { get; set; }
        public string To { get; set; }
        public PacketType PacketType { get; set; }
        public T Container { get; set; }

        public Packet()
        {
        }

        public Packet(string name, PacketType packetType, T container)
        {
            Name = name;
            PacketType = packetType;
            Container = container;
        }
    }

    public enum PacketType
    {
        Command,
        Data
    }

If I need to send information about files I just create a packet with the necessary structure CreatePacket<FilesInfo>(filesInfo) and then serialize it and send it to client\\server. 如果需要发送有关文件的信息,我只需创建一个具有必要结构CreatePacket<FilesInfo>(filesInfo)的数据包,然后对其进行序列化并将其发送到client \\ server。

But how I can deserialize data on receiving side? 但是如何在接收端反序列化数据? I don't know what is object type the packet is. 我不知道数据包是什么对象类型。 Is there any other way or library or something to solve my problem? 是否有其他方法或库或其他东西可以解决我的问题? Also I don't want to use WCF because my app should work on machines with .NET 2.0 installed. 另外,我也不想使用WCF,因为我的应用程序应该可以在装有.NET 2.0的计算机上运行。

Both chrfin and haiyyu have the same and a good idea. Chrfin和haiyyu都有相同的想法。 Below is the minor twist of using a Packet Base class to hold your type data on construction. 下面是使用Packet Base类在构造中保存类型数据的细微差别。 You serialize a Packet< T > and deserialize to a Packet. 您对Packet <T>进行序列化,然后反序列化为Packet。 Use is pretty simple then. 然后,使用非常简单。 Still the trick as already mentioned is to make the Type easily accessible. 如前所述,技巧仍然是使Type易于访问。

class Program
{
    static void Main(string[] args)
    {
        var pack = new Packet<int>() { Payload = 13 };
        var serializedData = pack.Serialize();
        var deserializedData = Packet.Deserialize(serializedData);
        Console.WriteLine("The payload type is:" + deserializedData.PayloadType.Name);
        Console.WriteLine("the payload is: " + deserializedData.Payload);
        Console.ReadLine();
    }
}



[Serializable]
public class Packet
{
    public Type PayloadType { get; protected set; }
    public object Payload { get; protected set; }
    public static Packet Deserialize(byte[] bytes)
    {
        return (Packet)(new BinaryFormatter()).Deserialize(new MemoryStream(bytes));
    }
}

[Serializable]
class Packet<T> : Packet
{
    public Packet()
    {
        PayloadType = typeof(T);
    }
    public new T Payload 
    {
        get { return (T)base.Payload; } 
        set { base.Payload = value; } 
    }

    public override string ToString()
    {
        return "[Packet]" + Payload.ToString();
    }

    public byte[] Serialize()
    {
        MemoryStream m = new MemoryStream();
        (new BinaryFormatter()).Serialize(m, this);
        return m.ToArray();
    }
}

Both the server and the client application have to use the same type. 服务器和客户端应用程序都必须使用相同的类型。 The sender can then tell the receiver the type of the data as a string, the receiver will then be able to get the type using Type.GetType(). 然后,发送方可以将字符串的类型告知接收方,然后接收方将能够使用Type.GetType()获取类型。

You could encapsulate the paket in a container which also contains the type: 您可以将包装袋封装在还包含以下类型的容器中:

public class Container
{
    public Type PacketType { get; set; }
    public byte[] Packet { get; set; }
}

and then 接着

Container c = (Container)cSerializer.Deserialize(/*Your Received Packet*/);
Packet<c.PacketType> paket = 
    (Packet<c.PacketType>)pSerializer.Deserialize(new MemoryStream(c.Packet));

or you could require that T always extens a Base-class and then use that on the receiving side: 或者您可以要求T总是扩展一个基类,然后在接收端使用它:

Packet<BaseClass> paket = 
    (Packet<BaseClass>)pSerializer.Deserialize(new MemoryStream(/*Data*/));

If you are useing XML serialization, this seems to work well.... 如果您使用的是XML序列化,这似乎很好用。

private string GetClassNameFromXMLSerializedString(string xml)
    {
        xml = xml.Substring(xml.IndexOf(">\r\n<") + 3, 50);//get second XML element
        return xml.Substring(1, xml.IndexOf(' ') - 1);//get class name
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将对象转换为C ++ / CLI中不知道其类型参数的通用列表? - How can I cast an Object to a generic List I don't know the type parameter of in C++/CLI? 如何投放清单 <Object> 列出 <Foo> 当foo是类型变量并且我不知道类型时 - How can I cast List<Object> to List<Foo> when foo is a type variable and I don't know the type 如何将XmlNode []反序列化为T类型? - How can I deserialize an XmlNode[] into type T? 如何设置targetPi? 我认为定义不正确,但我不知道该如何解决? - How can I set targetPi? I think definition is not right but I don't know how can I fix this? 如何比较两个 IEnumerable<T> 在 C# 中,如果我不知道实际的对象类型? - How to compare two IEnumerable<T> in C# if I don't know the actual object type? 当我不知道我使用什么类时如何反序列化 json 数组? - How to deserialize json array when i don't know what class i use? 如何反序列化我不知道的对象 - How to deserialize an object that i dont know 当事先不知道 object 类型时,如何反序列化 JSON? - How can I deserialize JSON when the object type is not known beforehand? 当我只知道祖先类的类型时,如何反序列化XML? - How can I deserialize an XML, when I only know the type of an ancestor class? 我需要获取特定对象属性的值,但不知道 object 的类型 - I need to get a value of specific object's property, but don't know the type of the object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM