C# 为什么我需要一个无参数构造函数?

C# 为什么我需要一个无参数构造函数?,c#,C#,可能重复: 我得到的运行时错误如下所述 Message=OutlookAddIn1.DeviceRegistrationRequest无法序列化,因为它没有无参数构造函数 我非常清楚为什么(错误消息中提到)以及如何解决它(空构造函数的简单添加)。我不清楚的是为什么需要它。我找到了 但它主要是关于MVC的,它与我的程序(CRM Dynamics的一个控制台客户端)无关。它是必需的,这样不了解参数化构造函数的代码就可以根据无参数构造函数可用的约定构造一个对象 在反序列化时,需要对象实例,因此反序列

可能重复:

我得到的运行时错误如下所述

Message=OutlookAddIn1.DeviceRegistrationRequest无法序列化,因为它没有无参数构造函数

我非常清楚为什么(错误消息中提到)以及如何解决它(空构造函数的简单添加)。我不清楚的是为什么需要它。我找到了
但它主要是关于MVC的,它与我的程序(CRM Dynamics的一个控制台客户端)无关。

它是必需的,这样不了解参数化构造函数的代码就可以根据无参数构造函数可用的约定构造一个对象

在反序列化时,需要对象实例,因此反序列化过程将使用此构造函数创建一个实例。

现在不了解报告问题的确切细节,但通常会说:

序列化需要默认值
ctor
,以便能够构造类型的对象。如果你没有它,它是无法做到的。它无法找到正确的参数来传递给带参数的
ctor
,因此它需要“清除”无参数的ctor。

不,这与MVC无关(对不起,我误读了你的帖子)。它只是关于普通C#py对象的创建。你看,以这个类为例:

public class Why {
    public Why(int x, int y) { }
}
当要反序列化和构造对象时,反序列化程序如何知道传递什么?他猜不到。因此,框架要求可序列化对象必须具有无参数构造函数,因此“仅创建”是安全的,并且您有责任通过属性设置整个状态


注意:顺便说一下-注意构造函数不必是公共的。大多数序列化程序都能很好地处理私有的无参数构造函数,或者根本不使用,如果它们实现为使用未初始化的对象构造,则至少在.Net完整配置文件中可以从反射中获得该构造。

用于反序列化以生成实例。如果你想隐藏它,你可以进行私有或内部构造。

这是因为反序列化程序需要能够轻松地创建类的实例并用数据填充它


如果没有无参数构造函数,反序列化程序将不得不猜测要发送给构造函数的参数。如果有一个约定遵循构造函数应该具有的参数,那么这可能会相当好,但最简单的约定是应该有一个没有参数的构造函数。

您的类只需要一个无参数构造函数,因为您正在使用一个库(听起来像
XmlSerializer
,可能是间接的)期望并使用该构造函数。这确实是一种非常方便的创建对象的方法,因为它允许:

object obj = Activator.CreateInstance(type);
用法

然而!这不是所有序列化程序的固有要求:

  • 有些序列化程序不使用任何构造函数(还有另一种创建对象的方法,完全跳过构造函数步骤)
  • 有些序列化程序允许您提供自己的工厂方法来创建新实例

不一定是XML,它通常是可序列化的,但它是非常相似的,这只是XML序列化的一个要求。这本身不是一项要求。例如,二进制格式化程序不需要无参数构造函数,甚至不需要私有构造函数。您的最后一条评论不太正确:对于许多其他序列化程序(
BinaryFormatter
DataContractSerializer
,等等),甚至不使用私有的无参数构造函数(并且不是必需的)。有些会使用私有构造函数,但通常即使这样也不会要求它。是的,有些序列化程序可以这样做-因为有些使用“肮脏的技巧”,比如创建未初始化的对象:)不过,我喜欢这个解释,由于它不涉及太多细节,而且在面向对象的意义上非常“自然”,因此,外部结构(反序列化对象)会看到
私有的
构造函数,并且在包含它的类中的任何地方都没有引用,这听起来非常令人惊讶。我试着解释一下,实际上,很少有序列化程序需要无参数的constructor@MarcGravell:同意,但是OP使用的那个似乎是一个真正需要它的人。我的观点是这样的措辞:“序列化需要默认的构造函数”。。。嗯,不完全是这样的:一个特定的序列化程序可能需要它,但序列化不需要这样的东西。@MarcGravel:啊,好的,更正了,thx。你能提供序列化程序不使用任何无参数构造函数吗?而
的回答是,任何序列化程序类都需要一个无参数构造函数。
。不,它可以创建一个未初始化的对象并填充所有字段(包括属性),例如
object myFoo=FormatterServices.GetUninitializedObject(typeof(Foo))