views:

524

answers:

1

I'm being presented with the following Exception when trying to serialize a class that contains enums in an obfuscated project:

ProtoBuf.ProtoException: The default enum value X is not defined for the optional property Y

If I exclude all affected enums from obfuscation everything runs fine, however, I switched to protobuf.net to be able to obfuscate more code content so I hope there is a better solution.

So is it the obfuscator which messes around to much for protobuf.net or am I declaring my enums the wrong way?

I have tried:

    [ProtoContract]
    public enum X
    {
        Y, Z
    }

and

    [ProtoContract]
    public enum X
    {
        Y=0, Z=1
    }

also without a contract at all and several other not so obvious things but nothing except exclusion works. By the way: Is there an example somewhere what we have to do with enums when using protobuf.net?

A: 

Hmmm.... I'm honestly not aware of obfuscation issues with enums; I will have to prepare a test case to investigate.

It would help if you could tell me what obfuscation tool you are using. It would also help to see how you are specifying the default value (i.e. the property definition).

Note that it only really considers [ProtoEnum] in the case of enums (the [ProtoContract] can be used to give it a name, but this isn't used unless you are generating .proto files, which is very unlikely) - but I don't expect it to impact anything in this case (this is used to change the value "on the wire" to different values than are in .NET). As for examples; I confess I'm behind on the documentation - but the enum test cases here show typical usage.

I've logged this as Issue 59; if you could let me know the details above (either here, or e-mail me - see my profile), I'll try to investigate.

(if you didn't know, I'm the author of protobuf-net)


I tried the following (using .NET Reactor) and it worked fine... the implicit default of zero on enum values is the most likely suspect. Can you supply a test-case that shows it failing?

using System;
using ProtoBuf;

[ProtoContract]
class Foo {
    static void Main() {
        Foo foo = new Foo { Bar = MyEnum.B };
        Console.WriteLine(foo.Bar);
        Foo clone = Serializer.DeepClone(foo);
        Console.WriteLine(clone.Bar); // Expect "B"
    }

    [ProtoMember(1)]
    public MyEnum Bar { get; set; }
}
enum MyEnum { A, B, C }
Marc Gravell
Hi Marc, I'm using .Net Reactor. Don't know what you mean with the default value (property definition) maybe that's the problem? :P I just use the enums as presented in the code sample. I took a look at the examples already, had no success however. I'm not generating proto files. Maybe I'm not seeing the obvious here - can you give me another example on how to use 'standard' enums in protobuf.net?
So where are you using this? For example, do you have a property "public X SomeProp {get;set;}"... is this marked [DefaultValue(...)] (for some ...)? Is it marked [ProtoMember(someTag, IsRequired=true)]? (I'm trying to figure out which branch it is going into...)
Marc Gravell
Looking at your example I would say that I'm doing it the same way here. If I can isolate a test case I'll post it.