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

时间:2016-01-20 08:06:32

标签: c# xmlserializer

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

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

[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无法序列化,因为它没有无参数构造函数。

一种解决方法是这样的:

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没有看到带有参数的构造函数都具有默认值。对此有更好的解决方法吗?

提前致谢!

1 个答案:

答案 0 :(得分:3)

我们必须转到编译器级别才能理解带有可选参数的方法实际上是具有非可选参数的方法的compile-time substitution

换句话说,没有真正的“带默认值的可选参数”。它是一个“非可选参数,在编译时替换”,但涂有合成糖,称为“带有默认参数的可选参数”,因为C#4.0 设计时间

“带有默认值的可选参数”只是设计时的概念,而不是编译/运行时的概念。

为了说明,假设你有:

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需要无参数构造函数。这是很好的解释here