Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我应该使用对象初始值设定项还是构造函数?_C#_Constructor_Object Initializer - Fatal编程技术网

C# 我应该使用对象初始值设定项还是构造函数?

C# 我应该使用对象初始值设定项还是构造函数?,c#,constructor,object-initializer,C#,Constructor,Object Initializer,我刚刚了解了对象初始值设定项,并想知道何时使用它们的最佳实践是什么 以下是我读到的关于他们的内容: 很明显,它们是创建匿名类型所必需的,但我想知道,在所有其他情况下,我是否应该尝试使用它们而不是普通构造函数。我目前发现使用它们时存在以下问题: 分配的属性必须是可更改的。这似乎 不需要,因为如果将数据传递给构造函数,我可以 如果提供的数据不正确,请在此处进行检查并使对象创建失败 不足或错误。如果数据可以指定属性I 突然必须弄清楚我的对象的状态是什么,是否 一切都被正确地创造出来了,或者我可能是哪种

我刚刚了解了对象初始值设定项,并想知道何时使用它们的最佳实践是什么

以下是我读到的关于他们的内容:
很明显,它们是创建匿名类型所必需的,但我想知道,在所有其他情况下,我是否应该尝试使用它们而不是普通构造函数。

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

  • 分配的属性必须是可更改的。这似乎 不需要,因为如果将数据传递给构造函数,我可以 如果提供的数据不正确,请在此处进行检查并使对象创建失败 不足或错误。如果数据可以指定属性I 突然必须弄清楚我的对象的状态是什么,是否 一切都被正确地创造出来了,或者我可能是哪种状态 在
  • 分配的属性必须是公共的。这意味着对可能是私有的东西的访问必须公开,然后通过使用接口或类似的东西进行限制

  • 因此,我的工作原理是:不要使用对象初始值设定项,因为它们会鼓励愚蠢的事情。

    我相信你在混淆事情

    对象初始值设定项将调用类的默认(或指定)构造函数!因此,您不能真正使用对象初始值设定项而不是普通构造函数。因此,当使用对象初始值设定项时,无论如何都要调用构造函数


    如果您对正在设计的类的对象初始值设定项感到疑惑,那么答案仍然适用。确保提供有意义的必要构造函数。您无需执行任何特殊操作即可启用/允许对象初始值设定项。它们是C#编译器自3.0版以来提供的语法糖,允许类的用户在构建后立即初始化类的公共成员。

    一个好的经验法则是:

    • 如果需要使类正常工作,那么它应该是一个构造函数参数
    • 如果更改它会破坏类,那么它应该是一个构造函数参数
    • 如果它是可选的,有一个健全的默认值,和/或简单而安全地更改类的行为,那么它应该是一个初始值设定项
    初始化器的主要优点是,在创建对象时不必设置它们——您可以稍后根据其他逻辑设置它们

    我想知道,在所有其他情况下,我是否应该尝试更喜欢它们而不是普通的构造函数

    我会说不

    建设者有很多优势。使用构造函数,编译器将强制向您的类型提供所有必需的数据。这意味着您可能无法创建处于无效状态的类型实例,这允许您主动预防许多bug

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

    通常,类运行所需的任何内容都应该在构造函数中进行。对象初始值设定项仍然可以使用,即使您有一个自定义构造函数,但应该只用于在类上设置为可选的数据。在初始化中混合使用这两种方法很好,这意味着您可以执行以下操作:

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

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

    这可能有些主观。有一个不可变的类型吗?需要封装状态的对象?对象声明可注入依赖项?更喜欢构造函数。有一个简单(但可变)的DTO吗?请随意使用初始值设定项语法。使用对您试图实现的目标有意义的工具。即使在一个简单的DTO中,我仍然会对类所需的任何内容使用构造函数参数。我同意这一点,除非您使用构建器类纯粹是初始化不可变类的私有构造函数。那就很好了。当然,对于范围很窄的事情也没关系。对象创建失败的唯一方法就是抛出异常。正如Miky所说,你把事情弄糊涂了。对象初始值设定项只能用于生成更干净的代码。您仍然编写相同的底层代码,这只是它的使用方式。请参阅Reed在所做链接中的答案@dugas@Bobson:他的意思是,如果使用属性初始化对象,则必须能够在不设置该属性的情况下创建该对象。因此,使用对象初始值设定项将调用默认构造函数。是,另外,如果使用对象初始化器的原因是可读性,那么在构造函数中考虑命名参数,而不是。