【问题标题】:C# constructorsC# 构造函数
【发布时间】:2011-03-30 12:46:17
【问题描述】:

有人可以建议我在编写 C# 构造函数时采用什么方法吗?

在其他语言中,例如C++,一切都很好 - 您通常不会使内部字段可见并为它们提供 getter / setter。

这意味着,您可以为您的类提供构造函数,这些构造函数会初始化所有/部分本地成员并感到高兴。


C#,然而,有properties,它允许我们写这样的东西:

Class x = new Class { Field1 = new Field1 ...., Field2 = new Field2 }

这允许对对象构造进行链接,并且我认为可以删除许多构造函数,如果我们没有properties,这将是必需的。

将它与属性的默认值相结合,正如我所假设的,我们可以完全摆脱非专业构造函数,它们实际上做了一些工作。

现在 - 是否可以删除冗余构造函数并允许通过字段初始化来构造对象?

这种方法的缺点是什么?有人能给出关于结合使用字段和构造函数的一般性建议,可能是rules of thumb

谢谢。

【问题讨论】:

标签: c# constructor field initializing


【解决方案1】:

我自己的经验法则很简单:如果完全构造对象需要某些东西,它应该是一个 ctor 参数。

一个很好的例子是 StreamReader 或 BinaryReader 等 Stream 帮助器对象之一。如果没有关联的 Stream 对象,它们就无法运行,因此必须在构造函数中指定。

【讨论】:

    【解决方案2】:

    在我看来,使用你所说的冗余构造函数并没有错。如果定义构造函数对您来说足够有意义,那可能是因为确实需要这样做。

    【讨论】:

      【解决方案3】:

      构造函数可用于强制消费者向类提供值。

      我的经验法则是字段用于可选数据,而构造函数可用于强制所需数据。

      不过,这个问题是一种错误的二分法。 C++ 的行为方式与 C# 相同 - “字段”(实际上是属性 - 字段是类级变量)通常用作设置内部值的 getter/setter,并且允许您设置字段的 new 语法只是的简写

      Class x = new Class();
      x.Field1 = new Field1();
      x.Field2 = new Field2();
      

      【讨论】:

        【解决方案4】:

        最佳实践是创建一个处于可用状态的对象;尽量限制对属性设置器的依赖。

        它减少了您创建不完整对象并导致代码不那么脆弱的机会。

        【讨论】:

          【解决方案5】:

          您发布的代码使用了所谓的对象初始化器,它们实际上只是最近才引入的语法糖。使用对象初始化器只是调用构造函数设置属性的一种简写方式。您应该继续在 C# 中使用构造函数,就像在其他语言中使用构造函数一样——一般规则是,如果一个类需要一个对象或值才能正确初始化,则该参数应该通过构造函数传递。如果该值不是必需的,则将其设为可设置的属性是合理的。

          一般来说,我尽可能避免使用 setter (有很多很多情况下是不可能的)。

          【讨论】:

            【解决方案6】:

            在 XAML 中使用公共无参数构造和属性初始化的方法很流行(必需?),很多 WPF 玩具都这样做。

            您面临的唯一问题是部分初始化的对象,但是您可以在尝试使用这些字段之前简单地验证对象状态。

            就我个人而言,我在构造函数中创建了临界值参数,我从对象的副本和一系列可选参数中创建了复制构造函数,但我还没有创建需要 XAML 使用的东西。

            【讨论】:

            • 我认为最初的问题不是关于可选参数,而是关于对象初始化器。但是,可选参数当然是这里的另一种选择!
            • 它属于摆脱专门的构造函数点,但是是的,它没有被直接提及。让我的回答与其他人略有不同:-)
            【解决方案7】:

            对象初始化语法只是一个语法糖。即使在 C# 1 中,您也可以编写

            Class c = new Class();
            c.Property1 = value1;
            c.Property2 = value2;
            c.Property3 = value3;
            ....
            

            C# 3 基本上将语法缩短为:

            Class c = new Class 
            {
               Property1 = value1, 
               Property2 = value2, 
               Property3 = value3
               ....
            }
            

            counstructor的重点不是只设置字段,constructor应该根据参数在逻辑上构造对象,这样当constructor返回时,你得到的是一个可以使用的对象。

            【讨论】:

              【解决方案8】:

              可以吗?嗯,这取决于...

              为了使用对象初始化器,您需要向所有字段公开公共设置器,您可能不希望这样做。如果您愿意公开它们,那么我会说继续并删除构造函数。然而,仅仅因为你可以做某事并不意味着你应该。如果你发现你的所有字段都是可公开设置的,我会说删除构造函数应该是你做的事情,不要为了让你删除构造函数而使字段可设置。

              【讨论】:

                【解决方案9】:

                我怀疑您在这里指的是域对象,但在服务的情况下,通过构造函数注入服务的依赖项会使服务更加自我记录,而不是“更新”您的依赖项。此外,这使您可以更轻松地使用依赖注入容器。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2014-05-27
                  • 2011-04-03
                  • 2010-12-16
                  • 2011-04-19
                  • 2020-05-14
                  • 1970-01-01
                  • 2018-06-04
                  • 2013-06-16
                  相关资源
                  最近更新 更多