【问题标题】:How to serialize and deserialize a class with byte array as a member in c#如何在c#中序列化和反序列化字节数组作为成员的类
【发布时间】:2014-05-05 08:56:06
【问题描述】:

我正在尝试以字节流的形式在 2 个进程之间发送数据,这对于几乎所有类都可以正常工作,但我遇到的一个问题是,如果对象的类内部有一个字节数组,则反序列化会失败它并给我一个错误,说明无法加载发生序列化的程序集。我不能在此处包含程序集,因为发送者和接收者都是不同的应用程序。

有没有办法解决这个问题?

编辑:很抱歉,即使是普通类也无法在另一端反序列化

编辑:两个应用程序之一使用.Net 2.0

public static byte[] SerializeToByteArray(this object obj)
{
    if (obj == null)
    {
        return null;
    }
    var bf = new BinaryFormatter();
    using (var ms = new MemoryStream())
    {
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }
}

public static T Deserialize<T>(this byte[] byteArray) where T : class
{
    if (byteArray == null)
    {
        return null;
    }
    using (var memStream = new MemoryStream())
    {
        var binForm = new BinaryFormatter();
        memStream.Write(byteArray, 0, byteArray.Length);
        memStream.Seek(0, SeekOrigin.Begin);s
        var obj = (T)binForm.Deserialize(memStream);
        return obj;
    }
}

【问题讨论】:

  • 您使用哪种形式的序列化?请添加一些源代码来说明您的情况
  • 我正在使用内存流进行序列化和反序列化.....
  • BinaryFormatter 需要确切版本的程序集,其中定义了要序列化/反序列化的类。你需要切换到另一种形式的序列化
  • 您可以将一个程序集与您想在两个应用程序中使用的数据类型一起使用。也许序列化也可以在该程序集中解决。
  • 嘿抱歉回复晚了,我就是这么做的,现在效果很好!谢谢!

标签: c# arrays serialization deserialization


【解决方案1】:

我建议你使用DataContractSerializer(这个 MSDN 链接也有如何用属性装饰类的示例)。

然后您可以轻松地将此类(反)序列化为二进制形式:

public static byte[] SerializeToByteArray<T>(this T obj) where T : class
{
    if (obj == null)
    {
        return null;
    }
    using (var ms = new MemoryStream())
    {
        var serializer = new DataContractSerializer(typeof(T));
        serializer.WriteObject(ms, obj);
        return ms.ToArray();
    }
}

public static T Deserialize<T>(this byte[] byteArray) where T : class
{
    if (byteArray == null)
    {
        return default(T);
    }
    using (var memStream = new MemoryStream(byteArray))
    {
        var serializer = new DataContractSerializer(typeof (T));
        var obj = (T) serializer.ReadObject(memStream);
        return obj;
    }
}

使用 return default(T); 而不是 return null; ,因为 T 可能不可为空
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/default

[更新] 警告!这仍然不是最好的解决方案,因为您必须在两个应用程序中定义完全相等的类并将它们作为通用参数传递给这些函数

[编辑] 由于您必须使用 .net 2.0,因此您需要回退到 XMLSerialization。它不如 DataContract 序列化方便,但它应该可以工作。这里是starting page for this topic on MSDN 下面是序列化/反序列化的代码

public static byte[] SerializeToByteArray<T>(this T obj) where T : class
{
    if (obj == null)
    {
        return null;
    }
    using (var ms = new MemoryStream())
    {
        var serializer = new XmlSerializer(typeof(T));
        serializer.Serialize(ms, obj);
        return ms.ToArray();
    }
}

public static T Deserialize<T>(this byte[] byteArray) where T : class
{
    if (byteArray == null)
    {
        return null;
    }
    using (var memStream = new MemoryStream(byteArray))
    {
        var serializer = new XmlSerializer(typeof(T));
        var obj = (T)serializer.Deserialize(memStream);
        return obj;
    }
}

【讨论】:

  • 实际上我需要类的数量完全相同,那里没有问题。真正的问题是在.Net 2.0 上运行的那些应用程序之一。据我检查,它不支持 DataContractSerializer 类
  • 对于不太详细的问题,我们深表歉意
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
  • 1970-01-01
  • 2016-07-13
相关资源
最近更新 更多