【问题标题】:Why do I need a parameterless constructor? [duplicate]为什么需要无参数构造函数? [复制]
【发布时间】:2012-09-15 16:40:06
【问题描述】:

可能重复:
Why XML-Serializable class need a parameterless constructor

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

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

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

【问题讨论】:

  • 不一定是 XML,它通常是可序列化的,但非常接近重复

标签: c#


【解决方案1】:

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

object obj = Activator.CreateInstance(type);

用法。

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

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

【讨论】:

  • 您能否提供不使用任何无参数构造函数的序列化程序?而Jamby 的答案是any Serializer Class need a parameterless constructor
【解决方案2】:

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

public class Why {
    public Why(int x, int y) { }
}

当你的对象被反序列化和构造时,反序列化器如何知道传递什么?他猜不透。因此,框架要求可序列化对象必须具有无参数构造函数,因此“只创建”是安全的,您有责任通过属性使整个状态可设置。

注意:顺便说一下 - 请注意构造函数不必是公开的。大多数序列化程序在使用私有无参数构造函数时表现得非常好,或者根本不使用,如果它们实现为使用未初始化的对象构造,那么至少在 .Net 完整配置文件中可以从 Reflection 获得。

【讨论】:

  • 这只是XML序列化的要求。这本身不是要求。例如,二进制格式化程序不需要无参数构造函数,甚至不需要私有构造函数。
  • 您的最后一条评论不太正确:对于许多其他序列化程序(BinaryFormatterDataContractSerializer 等),即使是私有无参数构造函数 也未使用(也未必需的)。有些人会使用私有构造函数,但通常即使这样也不会要求它。
  • 是的,一些序列化程序可以做到这一点 - 因为有些使用“肮脏的技巧”,比如创建未初始化的对象 :) 不过,我喜欢这个解释,因为它没有涉及太多细节并且非常“自然” ' 面向对象的意义
  • 一个构造函数是 private 并且在包含它的类的任何地方都没有被引用 将被外部结构(反序列化对象)看到,这听起来非常令人惊讶。我会试一试,谢谢你的解释。
【解决方案3】:

它是必需的,以便对参数化构造函数一无所知的代码可以根据无参数构造函数可用的约定构造您的对象之一。

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

【讨论】:

    【解决方案4】:

    为了反序列化创建一个实例。如果你想隐藏它,你可以做私有或内部构造。

    【讨论】:

      【解决方案5】:

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

      如果没有无参数构造函数,反序列化器将不得不猜测要发送给构造函数的参数。如果有一个关于构造函数应该有哪些参数的约定,那么这可能会很好地工作,但最简单的约定是应该有一个没有参数的构造函数。

      【讨论】:

      • 不,它可以创建一个未初始化的对象并填写所有字段(包括属性),例如object myFoo = FormatterServices.GetUninitializedObject(typeof(Foo));.
      【解决方案6】:

      现在不要准确报告问题的详细信息,但一般来说:

      你的序列化需要默认 ctor 以便能够构造你类型的对象。如果你没有它,它就没有办法做到这一点。它无法弄清楚正确的参数传递给ctor with 参数,因此它需要“清除”无参数ctor。

      【讨论】:

      • 其实很少有序列化器需要无参构造函数
      • @MarcGravell:同意,但是 OP 使用的那个似乎那个实际上需要它。
      • 我的意思是措辞:“序列化需要默认 ctor”...嗯,不完全是:特定的序列化程序可能需要它,但 序列化 不需要这样的东西。
      • @MarcGravell:嗯,好的,已更正,谢谢。
      猜你喜欢
      • 2017-03-26
      • 1970-01-01
      • 2010-09-21
      • 2011-02-25
      • 1970-01-01
      • 2013-11-23
      相关资源
      最近更新 更多