【问题标题】:Should I use an object initializer or a constructor? [duplicate]我应该使用对象初始化器还是构造器? [复制]
【发布时间】:2013-03-21 18:27:23
【问题描述】:

我刚刚了解了对象初始化器,想知道何时使用它们的最佳实践是什么。

这是我读到的关于他们的内容:http://msdn.microsoft.com/en-us/library/vstudio/bb384062.aspx 它清楚地表明它们对于创建匿名类型是必要的,但我想知道在所有其他情况下我是否应该尝试更喜欢它们而不是普通构造函数。

【问题讨论】:

  • 这可能有点主观。有一个不可变的类型?需要封装状态的对象?声明可注入依赖项的对象?更喜欢构造函数。有一个简单(但可变)的 DTO?随意使用初始化语法。使用对您要完成的工作有意义的工具。
  • 即使在一个简单的 DTO 中,对于类的任何必需,我仍然会使用构造函数参数。

标签: c# constructor object-initializer


【解决方案1】:

我想知道在所有其他情况下我是否应该尝试使用它们而不是普通构造函数。

我会说不。

构造函数有很多优点。使用构造函数,编译器将强制为您的类型提供所有必需的数据。这意味着您可以使您无法创建处于无效状态的类型的实例,从而可以主动防止许多错误。

另一方面,对象初始化器会带来很多缺点。您必须为需要初始化的任何数据提供可公开设置的属性。它们在构建时不是必需的,因此您类型的用户可能会意外遗漏一些数据。

一般来说,构造函数中应该需要任何必需 才能让您的类发挥作用。即使您有自定义构造函数,仍然可以使用对象初始值设定项,但只能用于在您的类中设置可选的数据。在初始化中混合两者都很好,这意味着你可以这样做:

var yourInst = new YourClass(req1, req2) { OptionalProperty = opt1 }

这有助于减少所需的构造函数重载次数(类似于使用optional arguments,但没有可选参数中版本控制的一些缺点)。

【讨论】:

【解决方案2】:

我相信你把事情搞糊涂了。

对象初始化器调用类的默认(或指定)构造函数!所以你不能真正使用对象初始化器代替普通的构造函数。因此,当使用对象初始化器时,无论如何您都在调用构造函数。

如果您想知道您正在设计的类的对象初始化器,那么答案仍然适用。确保提供有意义的必要构造函数。您不需要做任何特别的事情来启用/允许对象初始化器。它们是自 3.0 版以来 C# 编译器提供的语法糖,允许类的用户在构造后立即初始化类的公共成员。

【讨论】:

  • 所以使用对象初始化器会调用默认构造函数。
  • 是的,可以是默认构造函数,也可以是与您的初始化程序匹配的专用构造函数。
【解决方案3】:

一个好的经验法则是:

  • 如果需要使类正常工作,它应该是构造函数参数
  • 如果改变它会破坏类,它应该是一个构造函数参数
  • 如果它是可选的、具有合理的默认值和/或简单而安全地更改类的行为方式,则它应该是一个初始化程序。

初始化器的主要优点是您不必在创建对象时设置它们 - 您可以稍后根据其他逻辑设置它们。

【讨论】:

    【解决方案4】:

    我目前发现使用它们存在以下问题:

    1. 分配的属性必须是可更改的。这似乎 不可取,因为如果将数据传递给构造函数,我可以 如果提供的数据是,请在此处检查并使对象创建失败 不足或错误。如果数据可以分配一个属性 I 突然要弄清楚我的对象的状态是什么,是否 一切都已正确创建或我可能处于哪个其他状态 在。
    2. 分配的属性必须是公共的。这意味着对原本可能是私有的事物的访问将不得不公开,然后通过使用接口或类似的东西加以限制。

    所以我的工作理论是:不要使用对象初始化器,它们会鼓励愚蠢的事情。

    【讨论】:

    • 我同意这一点,除非您使用构建器类纯粹是为了初始化不可变类的私有构造器。然后就完全没问题了。当然,对于范围狭窄的事情也可以。
    • 对象创建失败的唯一方法是抛出异常。
    • 正如 Miky 所说,你把事情搞糊涂了。对象初始值设定项只应用于制作更简洁的代码。您仍然编写相同的底层代码,这就是它的使用方式。在@dugas 制作的链接中查看 Reed 的答案
    • @Bobson:他的意思是,如果你使用属性来初始化对象,那么必须可以在不设置那个/那些属性的情况下创建它。
    猜你喜欢
    • 2011-03-10
    • 2015-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-24
    • 2015-05-01
    • 2013-06-27
    • 2012-08-14
    相关资源
    最近更新 更多