我写了一些效果很好的代码,但我不明白为什么它有效。我想序列化一个类,让我们说一个整数。所以这是该类的代码。
[Serializable]
public class TestClass
{
public int Variable;
}
现在我希望能够创建此类的实例并立即设置Variable
。所以我创建了一个构造函数,也为序列化器创建了一个私有的默认构造函数。
[Serializable]
public class TestClass
{
public int Variable;
private TestClass() {}
public TestClass(int value)
{
Variable = value;
}
}
所以在我使用它的代码中,默认参数变得很方便。所以我将该技术应用于公共构造函数。
[Serializable]
public class TestClass
{
public int Variable;
private TestClass() {}
public TestClass(int value = 0)
{
Variable = value;
}
}
这一切都很好,但为什么呢?我们现在没有两个具有相同定义的构造函数吗?即使我将默认构造函数设为public,一切正常。删除默认构造函数后,它会在序列化时失败。我的第一个猜测是.NET的XmlSerialize不检查具有默认参数的构造函数。但是为什么编译器仍然允许这个代码?
我对此很好奇,但也希望学习并更好地理解内部的工作方式。谷歌搜索没有带来任何有用的东西,可能只是因为我无法想到正确的搜索条件。
答案 0 :(得分:5)
XmlSerializer特别要求它序列化的类具有无参数构造函数,如果在私有构造函数中放置断点,则会注意到它在反序列化时遇到了问题。具有默认参数的构造函数不是无参数构造函数,它是一个构造函数,它接受编译器为您插入的参数。
无参数构造函数与仅具有默认参数(或相同情况下的任何方法)的构造函数的重载分辨率归结为特异性。在众多其他重载解析规则中,C#4.0语言规范(7.5.3.2更好的函数成员)声明:
否则,如果MP的所有参数都有相应的参数 而默认参数需要替换至少一个 MQ中的可选参数,然后MP优于MQ。
根据这些信息,我们可以简化并提出有关您拥有的构造函数的问题。当你说new TestClass()
时,应该选择哪一个?
我们已经指定了要传递给调用的所有参数。在 这种情况,它是零。
是否有一个构造函数,其中包含完全零参数 呼叫者?
如果是,请拨打电话。
如果没有,请拨打下一个最好的东西。在这种情况下,它是你的构造函数,它有默认参数。
请注意,XmlSerializer 不遵循这些规则。它特别知道它想要什么,并且如果你不提供它会抱怨。