如何使用protosharp序列化和反序列化List <myclass>?</myclass>

时间:2012-09-04 21:08:36

标签: c# serialization protocol-buffers protobuf-net

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace test_protosharp
{
    [Serializable]
    [ProtoBuf.ProtoContract]
    public class MyClass
    {
        [ProtoSharp.Core.Tag(1)]
        [ProtoBuf.ProtoMember(1)]
        public int MessageType { get; set; }

        [ProtoSharp.Core.Tag(2)]
        [ProtoBuf.ProtoMember(2)]
        public string Message { get; set; }
    }

    class Program
    {
        private static List<MyClass> _forSerialize;

        static void Main()
        {
            _forSerialize = new List<MyClass>
                                {
                                    new MyClass {MessageType = 0, Message = "Test1"},
                                    new MyClass {MessageType = 1, Message = "Test2"},
                                    new MyClass {MessageType = 2, Message = "Test3"},
                                    new MyClass {MessageType = 3, Message = "Test4"}
                                };

            // Test BinaryFormatter Serializer
            using (Stream fs = File.Create("test.bin"))
            {
                BinaryFormatter bin = new BinaryFormatter();
                bin.Serialize(fs, _forSerialize);
            }

            using (Stream fs = File.OpenRead("test.bin"))
            {
                BinaryFormatter bin = new BinaryFormatter();
                _forSerialize = (List<MyClass>)bin.Deserialize(fs);
            }

            if (_forSerialize.Count == 4)
                Console.WriteLine("BinaryFormatter serializer work");

            // Test protobuf-net Serializer
            using (FileStream fs = File.Create("test.protobuf-net"))
                ProtoBuf.Serializer.Serialize(fs, _forSerialize);

            using (FileStream fs = File.OpenRead("test.protobuf-net"))
                _forSerialize = ProtoBuf.Serializer.Deserialize<List<MyClass>>(fs);

            if (_forSerialize.Count == 4)
                Console.WriteLine("protobuf-net serializer work");

            // Test ProtoSharp Serializer
            using (FileStream fs = File.Create("test.ProtoSharp"))
                ProtoSharp.Core.Serializer.Serialize(fs, _forSerialize);

            using (FileStream fs = File.OpenRead("test.ProtoSharp"))
                _forSerialize = ProtoSharp.Core.Serializer.Deserialize<List<MyClass>>(fs);

            if (_forSerialize.Count != 4)
                Console.WriteLine("ProtoSharp serializer NOT work");            

            Console.ReadLine();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

protosharp不支持列表作为根对象;你将需要包装它:

public class SomeWrapper
{
    private readonly List<MyClass> items = new List<MyClass>();
    [ProtoSharp.Core.Tag(1)]
    public List<MyClass> Items { get { return items; } }
}
...
var tmp = new SomeWrapper();

tmp.Items.AddRange(_forSerialize);
using (FileStream fs = File.Create("test.ProtoSharp"))
    ProtoSharp.Core.Serializer.Serialize(fs, tmp);

using (FileStream fs = File.OpenRead("test.ProtoSharp"))
    _forSerialize = ProtoSharp.Core.Serializer.Deserialize<SomeWrapper>(fs).Items;

if (_forSerialize.Count == 4)
    Console.WriteLine("ProtoSharp serializer work");

这应该与protobuf-net输出相同(以字节为单位)。

然而,我会建议(也许不是非常谦卑)protobuf-net做同样的工作但是已经进行了大量的改进和优化,远远超出protosharp所提供的范围,另外还支持更多的场景。

-

编辑:有趣的是,它们不是相同的输出; protosharp有2个额外的字节...我会看看能不能找出原因...编辑编辑:啊,这只是零默认行为;别担心。有关信息,如果您按如下所示进行MessageType,则两个基于protobuf的序列化程序的输出(正如您希望并期望的那样)100%相同:

[ProtoSharp.Core.Tag(1)]
[ProtoBuf.ProtoMember(1, IsRequired = true)]
public int MessageType { get; set; }