Protobuf简单类型直接反序列化方法 (2)

支持简单对象的直接序列化与反序列化
我说的简单对象,就是系统定义的泛型集合与直接有TypeCode,并且不是object的对象。补充一下,我常用的几种。

内置类型

定义在System命名空间下的类型,包括DateTime,Int32之类的,都是直接System.类型名称的形式。

注意,int和float这种是不行的,需要使用Int32和Single。

泛型集合+内置类型

泛型集合定义在System.Collections.Generic这个命名空间,所以组合起来为System.Collections.Generic.泛型名称`参数数量[System.类型名称]。举两个例子:

List<string>的是System.Collections.Generic.List1[System.String]`。

Dictionary<int,string>的是System.Collections.Generic.Dictionary2[[System.Int32],[System.String]]`。

内置类型数组

直接在名称后添加[]即可,形式为System.类型名称[]

补充

序列化操作不要求序列化的类型和反序列化的类型完全一致,比如说Array可以与List,IEnumerable进行互换。因此,一些单独定义的、结构比较简单的类型,可以通过内置类型进行反序列化,就没有必要在反序列化的时候加载原始的类了,简化了操作。

[ProtoContract] public class Message { [ProtoMember(1)] public List<string> values { get; set; } } static void Main(string[] args) { var ps = new Message { values = new List<string> { "1346dfg", "31461sfghj", "24576sth" } }; using (FileStream ms = new FileStream("d:\\a.txt", FileMode.Create)) { Serializer.Serialize(ms, ps); } using (FileStream ms = new FileStream("d:\\a.txt", FileMode.Open)) { //List<string>反序列化,而无需使用Message类。这里Message的FullName是"ConsoleApp6.Program+Message" dynamic data = Serializer.Deserialize(Type.GetType("System.Collections.Generic.List`1[System.String]"), ms); Console.WriteLine(data[1]); } }

另外,对于上面的dynamic,由于编译的时候不检查,怕操作错误的同学可以进行类型转换。分享一个代码段,可能能有点帮助。

//转换对象为某一种类型 public static T ConvertTo<T>(object value) { return (T)Convert.ChangeType(value, typeof(T)); }

如果是限定的几种类型,可以使用switch语句进行判断,并将对象转成T,以进行类型安全的操作。如果不是的话,推荐使用接口来定义类的通用行为,这个中提供了一些建议,推荐看看。

参考资料

内置类型

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpggxj.html