1

Is there a technical reason that the serialization of an object is not working, when the constructor has parameters, but each of the parameters has a default value?

For example, lets say this is the a (pseudo-)class I would like to serialize:

[SerializableAttribute]
public class Parameter
{
    public Parameter(int p1 = -1, int p2 = -1, int p3 = -1, AnotherEnum p4 = AnotherEnum.Enum1)
    {
        P1 = p1;
        P2 = p2;
        P3 = p3;
        m_enum = p4;
    }

    private AnotherEnum m_enum;

    [DataMember(Name = "P1")]
    public int P1 { get; set; }


    [DataMember(Name = "P2")]
    public int P2 { get; set; }


    [DataMember(Name = "P3")]
    public int P3 { get; set; }

    [DataMember(Name = "P4")]
    public AnotherEnum Enum
    {
        get
        {
            return m_enum;
        }
        set
        {
            m_enum = value;
        }
    }
}

This would give me an exception:

Namespace.Parameter cannot be serialized because it does not have a parameterless constructor.

One workaround would be like this:

public Parameter() // or this(-1)
{
    P1 = -1;
    P2 = -1;
    P3 = -1;
    m_enum = AnotherEnum.Enum1;
}

public Parameter(int p1 /* remove default value */, int p2 = -1, int p3 = -1, AnotherEnum p4 = AnotherEnum.Enum1)
{
    P1 = p1;
    P2 = p2;
    P3 = p3;
    m_enum = p4;
}

I would like to know, why exactly the XMLSerializer does not see a constructor with parameters that all have default values. And are there better work arounds for this?

Thanks in advance!

Ian
  • 30,182
  • 19
  • 69
  • 107
Jannik
  • 2,310
  • 6
  • 32
  • 61
  • 3
    .NET 1 - XmlSerializer. C# 4 - default parameters. Maybe there just wasn't a compelling case to *add* this functionality at the same time. Every feature [Starts at minus 100 points](http://blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx) – Damien_The_Unbeliever Jan 20 '16 at 08:11
  • 1
    Optional parameters are a pure compiler trick, it flounders in reflection. Easiest way to see it go up in flames: var obj = Activator.CreateInstance(typeof(Parameter)); – Hans Passant Jan 20 '16 at 08:39

1 Answers1

3

We have to go to the compiler level to understand that the method with optional parameters are actually compile-time substitution of the method with non-optional parameters.

In other words, there is no real "optional parameter with default value". It is a "non-optional-parameter substituted at compile time" but coated with syntatical sugar called "optional parameter with default parameter" since C#4.0 during the design time.

"optional parameter with default value" is only a concept at the design time, not at the compile/run time.

To illustrate, assuming you have:

public Parameter(int p1 = -1, int p2 = -1, int p3 = -1, AnotherEnum p4 = AnotherEnum.Enum1)
{
    P1 = p1;
    P2 = p2;
    P3 = p3;
    m_enum = p4;
}

And you do:

Parameter pa = new Parameter(1);
Parameter pb = new Parameter(1, -1);

The two of them will be resulting in identical Intermediate Language (IL), although in design time they look different(!).

Additional note: as for why the XMLSerializer requires parameterless constructor. It is well-explained here.

Community
  • 1
  • 1
Ian
  • 30,182
  • 19
  • 69
  • 107
  • Thank you for the answer. To summarize the article: Does that mean in my case, that in my example the following statement new Parameter() will end up new Parameter(-1, -1, -1, MyEnum.Enum1) after compilation in every place I use that statement? – Jannik Jan 20 '16 at 08:35
  • @Jannik Yes, provided your constructor parameter is `public Parameter(int p1 = -1, int p2 = -1, int p3 = -1, AnotherEnum p4 = AnotherEnum.Enum1)` then whether you put 0, 1, 2, 3, or 4 arguments the same as the default value, the IL will be identical. – Ian Jan 20 '16 at 08:36
  • Alright then, BTW: Not sure, but I think you should delete the last third of your answer, I haven't really asked about why the XmlSerializer does need a default constructor, maybe you have misunderstood my question :) – Jannik Jan 20 '16 at 08:43
  • @Jannik ok, answer updated. :) I only left the link there, and it is not directed to "you" anymore as previous version was. I put it under "additional note". – Ian Jan 20 '16 at 08:46