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

本文关键字:方法 最佳 序列化 对象 使用 | 更新日期: 2023-09-27 17:49:24

我正在进行协作绘图(套接字编程),其中我必须发送和接收100到1000个Point of C# Class,所以我想知道发送和接收这些点的最佳方式是什么。我有两个选择…一个是List<Point>,另一个是Point[],使用BinaryFormatterJSON,但我已经读到JSON用于发送少量数据,我不知道它是否与C# window applications一起工作谢谢您的帮助

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

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

如果你想传输很多对象,不要使用JSON -它是一种文本格式,每个不必要的字符都是一个字节的空间浪费。如果你的对象使用20个字节,而它的文本表示使用100个字节(例如,因为字段名),那么对于大型集合来说,这是一个糟糕的选择,特别是在网络传输中。

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

二进制序列化是完全不同的事情。有很多序列化器:BinaryFormatter, Marc Gravell的protobuf-net, Migrant(我是合著者),还有很多很多其他的。

选择是困难的,并且是特定于领域的。你需要保留图形依赖关系吗?你有很多不同的物品或大的收藏吗?不同的库会给你不同的结果。

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

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

您需要随机访问您的点数吗?那么你可能需要一个数组。您是否需要创建一个可调整大小的集合并对其进行迭代?列表可能更好。

我运行了一个简单的测试,在BinaryFormatterMigrant上使用1000000个System.Windows.Point实例。无论我使用Point[]还是List<Point>,都没有真正的区别。

选择在你。

下面是我完成的测试的一个片段。代码不是很花哨,但是您可以毫不费力地将其更改为List<Point>。如果您需要一个简单的框架来序列化数据,我可能会推荐migration。请注意单行用法: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);
    }
}
}