简体   繁体   中英

SerializableAttribute on a constructor with optional parameters

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!

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM