akkadotnet / Hyperion

Polymorphic serialization for .NET
Apache License 2.0
277 stars 62 forks source link

System.NullReferenceException - when known types differ in serialization and deserialization process #188

Open jakubbukaj opened 4 years ago

jakubbukaj commented 4 years ago
public class SimplePerson
{
    public string Name { get; set; }
}

private static void Test()
{
    var serializer = new Hyperion.Serializer();
    var to = new List<SimplePerson>();
    to.Add(new SimplePerson { Name = "Joe" });
    to.Add(new SimplePerson { Name = "Richard" });

    byte[] serialized;
    using (var ms = new MemoryStream())
    {
        serializer.Serialize(to, ms);
        serialized = ms.ToArray();
    }

    serializer = new Hyperion.Serializer(new SerializerOptions(false, false, null, null, new[] { typeof(int) }));

    using (var ms = new MemoryStream(serialized))
    {
        var res = serializer.Deserialize(ms); // exception is thrown here
    }
}
jakubbukaj commented 4 years ago

System.OutOfMemoryException: 'Exception of type 'System.OutOfMemoryException' was thrown.' Will be thrown if I encapsulate serialized data by TransportObject.

     public class TranspObj
        {
            public Dictionary<string, object> Items
            {
                get { return _items; }
                set { _items = value; }
            }

            private Dictionary<string, object> _items = new Dictionary<string, object>();

            public T Get<T>(string key)
            {
                if (!_items.ContainsKey(key))
                    return default(T);

                return (T)_items[key];
            }

            public void Add(string key, object value)
            {
                _items[key] = value;
            }
        }

        public class SimplePerson
        {
            public string Name { get; set; }
        }

        private static void Test()
        {
            var serializer = new Hyperion.Serializer();
            var to = new TranspObj();
            to.Add("K1", new SimplePerson { Name = "Joe" });
            to.Add("K2", new SimplePerson { Name = "Richard" });

            byte[] serialized;
            using (var ms = new MemoryStream())
            {
                serializer.Serialize(to, ms);
                serialized = ms.ToArray();
            }

            serializer = new Hyperion.Serializer(new SerializerOptions(false, false, null, null, new[] { typeof(int) }));

            using (var ms = new MemoryStream(serialized))
            {
                var res = serializer.Deserialize(ms); // exception is thrown here
            }
        }
Aaronontheweb commented 4 years ago

I'm sorry, what was the expected vs. actual behavior here?

jakubbukaj commented 4 years ago

In the first case - if well known types differs (imagine client server application where server is already updated and client is connecting to updated server for its update) there should be more polite way to deal with these changes (e.g. hooking some event).

In case of "System.OutOfMemoryException" it seems there is some kind of error in memory allocation. I am sorry I should create two threads instead of one.