使用C#序列化对象的最佳实践/方法

rum*_*han 0 c# serialization json network-programming winforms

IM工作的协作绘图(套接字编程)在我所发送和收到100至1000 Point of C# Class,所以我想知道,是什么让发送和接收这些点最好的办法..我有两个选择..一个是List<Point>和其他正在Point[]使用BinaryFormatter或JSON,但是我已经阅读过JSON用于发送少量数据的信息,但我不知道它是否可以与C# window applicationsthanx一起使用以提供任何帮助

Pio*_*fer 5

序列化数据的方法有很多。

如果要传输很多对象,请不要使用JSON-这是一种文本格式,每个不必要的字符都会浪费字节空间。如果您的对象使用了20个字节,并且其文本表示形式使用了100个字节(例如,由于字段名称),那么对于大型集合(尤其是网络传输)而言,这是一个不好的选择。

当然,除非需要序列化的输出可读。我相信,那是使用JSON的唯一原因。

二进制序列化完全是另一回事。那里有许多序列化器:BinaryFormatter,Marc Gravell 撰写的protobuf-net,Migrant(我与人合着)以及许多其他序列化器。

选择是困难的并且是针对特定领域的。您需要保留图依赖吗?您有许多不同的对象或大型收藏吗?不同的库会给您不同的结果。

由于您的数据集不是很大(我假设我们正在谈论的是小类/结构Point),因此我将重点放在可读性上。您不想将代码设计为易于序列化,并且很少想要编写包装器(因为必须对其进行维护)。

使用在您的上下文中有意义的数据类型。

您是否需要随机获得积分?那么可能您需要一个数组。您是否需要创建可调整大小的集合并对其进行迭代?列表可能会更好。

我已经跑了一个简单的测试,使用百万System.Windows.Point情况下,无论是在BinaryFormatter和Migrant。我使用Point[]还是使用都没有真正的区别List<Point>。

这是你的选择。

这是我已完成的测试的摘要。代码不是很固定,但是您可以List<Point>毫不费力地将其更改为。如果您需要一个简单的框架来序列化数据,建议您使用Migrant。请注意单线用法:result = Serializer.DeepClone (source);;-)

using System;
using Antmicro.Migrant;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Windows;

namespace test15
{
class MainClass
{
    private static void EnsureEqual(Point[] source, Point[] result)
    {
        for (var i = 0; i < result.Length; ++i) {
            if (source [i] != result [i]) {
                throw new Exception ();
            }
        }
    }

    public static void Main (string[] args)
    {
        var source = new Point[1000000];
        Point[] result, binResult;
        var timer = new Stopwatch ();
        for (var i = 0; i < source.Length; ++i) {
            source [i] = new Point (i, i);
        }

        //Migrant
        timer.Start ();
        result = Serializer.DeepClone (source);
        timer.Stop ();
        EnsureEqual (source, result);
        Console.WriteLine ("Migrant time: {0}", timer.Elapsed);

        timer.Reset ();

        //Binary formatter
        var binaryForm = new BinaryFormatter ();
        using (var ms = new MemoryStream ()) {
            timer.Start ();
            binaryForm.Serialize (ms, source);
            ms.Position = 0;
            binResult = binaryForm.Deserialize(ms) as Point[];
            timer.Stop ();
        }
        Console.WriteLine ("Binary formatter time: {0}", timer.Elapsed);
        EnsureEqual (source, binResult);
    }
}
}
Run Code Online (Sandbox Code Playgroud)