question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Custom class serialization without default constructor does not work

See original GitHub issue

Describe the bug Custom class serialization without default constructor does not work

To Reproduce Steps to reproduce the behavior:

    [ServerRpc]
    public void TestServerRCP(Foo foo)
    {
    // foo is null
    }

    public class Foo : INetworkSerializable
    {
        public string Boo;
        public string Poo;

        public Foo(string boo, string poo)
        {
            Boo = boo;
            Poo = poo;
        }

        /// <inheritdoc />
        public void NetworkSerialize(NetworkSerializer serializer)
        {
            serializer.Serialize(ref Boo);
            serializer.Serialize(ref Poo);
        }
    }

Actual outcome Foo is null

Expected outcome

  • Provided constructor should be used instead, (if possible) or exception should be returned
  • Exception should be returned that the default constructor is missing.
  • Allow for custom constructors in serializer API

Environment (please complete the following information):

  • OS: Windows 10
  • Unity Version: 2020.3.5f1
  • MLAPI Version: 1.0.0

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
ArgentumVircommented, May 29, 2021

In case its useful to anyone else, in this thread (and the current documentation) the term default constructor is being used to refer to a parameterless constructor (this messed me up when googling a bit). To elaborate unnecessarily, this constructor only exists if you have explicitly defined it or you have defined no constructors (and so the default constructor given to you is a parameterless one)

tldr; In short, your receiver will receive null instead of the value you expect if no parameterless constructor is provided in the class you are trying to serialize.

Gratuitous examples for those who only read code and are allergic to text:

✔️ The following will serialize properly (C# gives you a default constructor since you didn’t declare any constructors at all and this default constructor is parameterless)

using MLAPI.Serialization;

public class Example : INetworkSerializable
{
    public int SomeVariable;

    public void NetworkSerialize(NetworkSerializer serializer)
    {
        serializer.Serialize(ref SomeVariable);
    }
}

❌ The following will NOT serialize properly, the receiver will just get null because you have defined a constructor with parameters, so C# will not give you a default one (which would have been parameterless)

using MLAPI.Serialization;

public class Example : INetworkSerializable
{
    public int SomeVariable;

    public void NetworkSerialize(NetworkSerializer serializer)
    {
        serializer.Serialize(ref SomeVariable);
    }

    public Example(int someVariable)
    {
        SomeVariable = someVariable;
    }
}

✔️ The following will serialize properly because a parameterless constructor was explicitly declared on the class

using MLAPI.Serialization;

public class Example : INetworkSerializable
{
    public int SomeVariable;

    public void NetworkSerialize(NetworkSerializer serializer)
    {
        serializer.Serialize(ref SomeVariable);
    }

    // You need this parameterless constructor for serialization to not return null
    public Example()
    {
    }

    public Example(int someVariable)
    {
        SomeVariable = someVariable;
    }
}
0reactions
ThusSpokeNomadcommented, Aug 21, 2022

@ShadauxCat, not urgent and also not triaged yet but I think it’d worth checking if we implemented RPC params new() (default parameterless constructor) constraint check on the ILPP side and closing this one off. There might be a minor update on the docs side (as we mentioned before above) but I actually want to just leave all this on your judgement.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Custom class serialization without default constructor does ...
Describe the bug Custom class serialization without default constructor does not work To Reproduce Steps to reproduce the behavior: ...
Read more >
c# - class can not do serialization without empty constructor
ClassName cannot be serialized because it does not have a parameterless constructor. The code goes like this: public void DoSerialize(string ...
Read more >
Cannot serialize without a default public constructor...
I'm having trouble (xml) serializing a class that I've placed a constructor in: [System.Serializable] public class Stat { public...
Read more >
Should custom deserialization happen in a constructor or ...
No, it should not. Serialization is orthogonal to the object and thus should be kept outside. Custom serialization belongs in a ...
Read more >
CA2229: Implement serialization constructors (code analysis)
The serialization constructor is required to deserialize, or recreate, objects that have been serialized using the ISerializable. GetObjectData ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found