带有可选参数的构造函数上的 SerializableAttribute

SerializableAttribute on a constructor with optional parameters

当构造函数有参数但每个参数都有默认值时,对象的序列化不起作用是否有技术原因?

例如,假设这是一个(伪)class 我想序列化:

[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;
        }
    }
}

这会给我一个例外:

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

一个解决方法是这样的:

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;
}

我想知道,为什么 XMLSerializer 没有看到参数都具有默认值的构造函数。有更好的解决方法吗?

提前致谢!

我们要到编译器层面去理解,带可选参数的方法实际上是带non-optional参数的方法的compile-time substitution

也就是说,没有真正的"optional parameter with default value"。它是一个 "non-optional-parameter substituted at compile time" 涂上了语法糖 自 C#4.0 以来称为 "optional parameter with default parameter"设计时间.

"optional parameter with default value"只是设计时的概念,compile/run时还没有。

为了说明,假设您有:

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

而你:

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

尽管在设计时它们看起来不同(!),但它们中的两个将产生相同的中间语言 (IL)。

补充说明:至于为什么XMLSerializer需要无参构造函数。是well-explainedhere.