使用c#序列化对象的最佳实践/方法
本文关键字:方法 最佳 序列化 对象 使用 | 更新日期: 2023-09-27 17:49:24
我正在进行协作绘图(套接字编程),其中我必须发送和接收100到1000个Point of C# Class
,所以我想知道发送和接收这些点的最佳方式是什么。我有两个选择…一个是List<Point>
,另一个是Point[]
,使用BinaryFormatter
或JSON
,但我已经读到JSON
用于发送少量数据,我不知道它是否与C# window applications
一起工作谢谢您的帮助
序列化数据的方法有很多。
如果你想传输很多对象,不要使用JSON -它是一种文本格式,每个不必要的字符都是一个字节的空间浪费。如果你的对象使用20个字节,而它的文本表示使用100个字节(例如,因为字段名),那么对于大型集合来说,这是一个糟糕的选择,特别是在网络传输中。
当然,除非您需要序列化的输出是可读的。我相信,这是使用JSON的唯一原因。
二进制序列化是完全不同的事情。有很多序列化器:BinaryFormatter
, Marc Gravell的protobuf-net, Migrant(我是合著者),还有很多很多其他的。
选择是困难的,并且是特定于领域的。你需要保留图形依赖关系吗?你有很多不同的物品或大的收藏吗?不同的库会给你不同的结果。
由于您的数据集不是很大(我假设我们谈论的是一个小类/结构Point
),我将重点放在可读性上。您不希望将代码设计为易于序列化的,并且您很少希望编写包装器(因为必须维护它们)。
使用在您的上下文中有意义的数据类型。
您需要随机访问您的点数吗?那么你可能需要一个数组。您是否需要创建一个可调整大小的集合并对其进行迭代?列表可能更好。
我运行了一个简单的测试,在BinaryFormatter
和Migrant
上使用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);
}
}
}