繁体   English   中英

protobuf-net没有使用私有setter序列化C#属性

[英]protobuf-net not serializing C# properties with private setters

我今天一直在使用protobuf-net,并且遇到了奇怪的情况。 下面的代码不会按预期反序列化。 最后两次反序列化尝试成功,但它们不正确。 当反序列化对象实际应设置为false时,将IsEmpty设置为true 我已经能够获得私人制定者的属性来序列化很好,但这一个表现不正常。 它与链式默认构造函数有关吗?

class Program2
{
    static void Main(string[] args)
    {
        var comp = new FooComparer();

        // this deserializes fine.  woot!
        using (var ms = new MemoryStream())
        {
            Console.WriteLine("Serializing an empty Foo");
            var args1 = new Foo();
            Serializer.Serialize(ms, args1);
            ms.Position = 0;
            var result = Serializer.Deserialize(ms);
            Console.WriteLine("Serialization successful: {0}", comp.Equals(args1, result));
            Console.WriteLine();
        }

        // this deserializes incorrectly
        using (var ms = new MemoryStream())
        {
            Console.WriteLine("Serializing a Foo with just a string");
            var args1 = new Foo("576000BJ1");
            Serializer.Serialize(ms, args1);
            ms.Position = 0;
            var result = Serializer.Deserialize(ms);
            Console.WriteLine("Serialization successful: {0}", comp.Equals(args1, result));
            Console.WriteLine();
        }

        // this deserializes incorrectly
        using (var ms = new MemoryStream())
        {
            Console.WriteLine("Serializing a Foo with an int");
            var args1 = new Foo(42);
            Serializer.Serialize(ms, args1);
            ms.Position = 0;
            var result = Serializer.Deserialize(ms);
            Console.WriteLine("Serialization successful: {0}", comp.Equals(args1, result));
            Console.WriteLine();
        }

        Console.WriteLine("Got dat 190% serialization");
    }
}

[ProtoContract]
class Foo
{
    private Foo(bool isEmpty, string fooString, int? fooInt)
    {
        this.IsEmpty = isEmpty;
        this.FooString = fooString;
        this.FooInt = fooInt;
    }

    public Foo() : this(true, null, null) { }
    public Foo(string foo) : this(false, foo, null) { }
    public Foo(int foo) : this(false, null, foo) { }

    [ProtoMember(10)] public bool IsEmpty { get; private set; }
    [ProtoMember(20)] public string FooString { get; private set; }
    [ProtoMember(30)] public int? FooInt { get; private set; }
}

class FooComparer : IEqualityComparer
{
    public bool Equals(Foo x, Foo y)
    {
        return (x == null && y == null) ||
                (x != null && y != null &&
                x.IsEmpty == y.IsEmpty &&
                String.Equals(x.FooString, y.FooString, StringComparison.Ordinal) &&
                x.FooInt == y.FooInt);
    }

    public int GetHashCode(Foo obj) { return 1; }   // don't care about this
}

编辑:我正在使用.NET 3.5与protobuf 2.0.0.666

这是隐式默认值行为。 最简单的修复可能是使用IsRequired = true标记IsEmpty(在属性属性上)。

在这里找到答案: c#protobuf-net在反序列化时,某些属性值始终为-1

为了节省空间,protobuf不会为值类型序列化默认值。 在此示例中, bool的.NET默认值为false 默认构造函数将IsEmpty属性设置为true ,并且由于我期望它具有的值与.NET默认值相同,因此protobuf会跳过保存该值,因此我从默认构造函数中获取值。

该解决方案是将IsRequired设置为TRUE,如Marc所说,或者在参数上使用[ProtoContract(10), DefaultValue(true)]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM