anerjan / protobuf-net

Automatically exported from code.google.com/p/protobuf-net
Other
0 stars 0 forks source link

When using interface: The type cannot be changed once a serializer has been generated #298

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Please include an e-mail address if this might need a dialogue!
==============
eric at entechsolutions.com

What steps will reproduce the problem?

I created a simple test case:

===============================
[ProtoContract]
    [ProtoInclude(101, typeof(Animal))]
    public interface IAnimal
    {
        [ProtoMember(1)]
        int Legs { get; set; }

        [ProtoMember(2)]
        bool HasFur { get; set; }

        [ProtoMember(3)]
        string Name { get; set; }
    }

    [Serializable]
    [ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
    [ProtoInclude(100, typeof(Dragon))]
    [ProtoInclude(101, typeof(Cat))]
    public class Animal : IAnimal
    {
        public int Legs { get; set; }
        public bool HasFur { get; set; }
        public string Name { get; set; }
    }

    [Serializable]
    [ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
    public class Dragon : Animal
    {
        public int FireCapacity { get; set; }
        public string History { get; set; }
        public DateTime DateOfBirh { get; set; }
    }

    [Serializable]
        [ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
    public class Cat : Animal
    {
        public int NumOfLives { get; set; }
        }

        [Test]
    public void Serialize_When_Interface_Works()
    {
        IAnimal dragon1 = new Dragon
            {
                Legs = 4,
                HasFur = false,
                Name = CacheTestUtils.RandomString(100),
                FireCapacity =  245,
                History = CacheTestUtils.RandomString(100),
                DateOfBirh = new DateTime(1229, 1, 4)
            };
        byte[] bytes = ProtoBufSerializer.Serialize(dragon1);

        IAnimal dragon2 = ProtoBufSerializer.Deserialize<IAnimal>(bytes);
    }

=====================================

On line:
IAnimal dragon2 = ProtoBufSerializer.Deserialize<IAnimal>(bytes);

I get exception:
ProtoBuf.ProtoException : The type cannot be changed once a serializer has been 
generated for Data.Animal 
(SpaFinder.SpaBooker.Infrastructure.Tests.Cache.Data.IAnimal)
  ----> System.InvalidOperationException : The type cannot be changed once a serializer has been generated for Data.Animal

What is the expected output? What do you see instead?

Expected not to throw an error

What version of the product are you using? On what operating system?

r480. Win 7

Please provide any additional information below.

Original issue reported on code.google.com by e...@entechsolutions.com on 21 Jun 2012 at 12:46

GoogleCodeExporter commented 9 years ago
In code I am using ProtoBufSerializer class
=================
public class ProtoBufSerializer
    {

        public static byte[] Serialize<T>(T obj) 
        {
            using (var memoryStream = new MemoryStream())
            {
                Serializer.Serialize(memoryStream, obj);
            }
        }

        public static T Deserialize<T>(byte[] data)
        {
            using (var memoryStream = new MemoryStream(data))
            {
                return Serializer.Deserialize<T>(memoryStream);
            }
        }
}

====================

Also CacheTestUtils.RandomString(100) just generates random strings

Original comment by e...@entechsolutions.com on 21 Jun 2012 at 12:54

GoogleCodeExporter commented 9 years ago
I had the exact same issue (same code).
Workaround: Use an abstract class instead of an interface.

Original comment by b3ls...@gmail.com on 17 May 2014 at 7:32