介绍
小编给大家分享一下c# Protobuf怎么做到0分配内存的序列化,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!
题目很简单,就是IMessage对象怎么变成Byte []
答案1:
msg.ToByteArray ()
这肯定不符合我们的要求
答案2:
using var memoryStream =, new MemoryStream (); 时间=using var  codedOutputStream new CodedOutputStream (memoryStream); msg.WriteTo (codedOutputStream); codedOutputStream.Flush (); memoryStream.ToArray ();
这里面memoryStream, codedOutputStream,还有ToArray都产生了一个对象,memoryStream内部还会多产生一个byte[]对象
不符合要求
答案3:
有人说你可以给memoryStream传递一个byte[]片,让memoryStream直接用byte []
var bytes =, new 字节(msg.CalculateSize ()); 时间=using var  memoryStream new MemoryStream (); 时间=using var  codedOutputStream new CodedOutputStream (memoryStream); msg.WriteTo (codedOutputStream); codedOutputStream.Flush ();
这次消息直接被序列化到字节里面去了,但是memoryStream对象,codecOutputStream还有memoryStream内部的byte[]都还在,我就序列化了一个对象,却产生了3个垃圾对象,
所以,来仔细看看CodedOutputStream类:
///, & lt; summary> ,,,///,Creates a new CodedOutputStream that writes directly 用, ,,,///,byte 数组只If more bytes 断开连接;written than fit 拷贝,数组, ,,,///,OutOfSpaceException will be 抛出。 ,,,///,& lt;/summary> ,,,public CodedOutputStream (byte [], flatArray),:,这(flatArray, 0, flatArray.Length) ,,,{ ,,,} ,,,///,& lt; summary> ,,,///,Creates a new CodedOutputStream that writes directly 用, ,,,///,byte array 片只If more bytes 断开连接;written than fit 拷贝,数组, ,,,///,OutOfSpaceException will be 抛出。 ,,,///,& lt;/summary> ,,,private CodedOutputStream (byte[],缓冲区,,int 抵消,,int 长度) ,,,{ ,,,,,this.output =,空; ,,,,,this.buffer =,缓冲; ,,,,,this.position =,抵消; ,,,,,this.limit =, offset +,长度; ,,,,,leaveOpen =,真的,,//,Simple way of avoiding trying 用dispose of a null 参考 ,,,}
提供了一个byte[]的构造函数,但是没提供切片的构造函数,好在有一个私有的构造函数
答案4:
这边就不写代码了,大概意思就是通过反射私有构造函数来构造一个CodedOutputStream对象,来省掉MemoryStream和他内部的byte []
现在离答案已经比较接近了,
那我们的问题是,能不能连CodedOutputStream也省掉呢?
答案5来了:
经过仔细观察,发现这个类没有使用流的情况下,就只需要修改缓冲区,限制,和位置几个成员就行了,虽然是私人成员,但是c#还是能修改
下来立马实践
delegate void ClearCodedOutputStream (CodedOutputStream 流,byte[],缓冲区,,int 抵消,,int 数); ,,,static ClearCodedOutputStream ResetCodedOutputStream; ,,,static CodedOutputStream CodedOutputStream =, new CodedOutputStream (new 字节[10]); ,,,static unsafe void 编码(IMessage 味精,byte[],缓冲区) ,,,{ ,,,,,ResetCodedOutputStream (codedOutputStream,缓冲区,,0,,buffer.Length); ,,,,,msg.WriteTo (codedOutputStream); ,,,,,codedOutputStream.Flush (); ,,,} ,,,static Action, MakeSetter (FieldInfo 字段) ,,,{ ,,,,,DynamicMethod m =, new DynamicMethod ( ,,,,,,,“setter",, typeof(空白),new 类型[],{,typeof (T) typeof (TValue),},, typeof(程序)); ,,,,,ILGenerator cg =, m.GetILGenerator (); ,,,,,cg.Emit (OpCodes.Ldarg_0); ,,,,,cg.Emit (OpCodes.Ldarg_1); ,,,,,cg.Emit (OpCodes.Stfld,字段); ,,,,,cg.Emit (OpCodes.Ret); ,,,,,return (Action ) m.CreateDelegate (typeof (Action )); null null null null null null null null null null null null null null null null null null null null null null null null null c# Protobuf怎么做到0分配内存的序列化