构造函数应该将自己的参数直接初始化为私有成员还是通过公共字段(C#centric)?

时间:2009-05-20 17:12:18

标签: c# constructor initialization

E.g。哪种方式更好

class Foo {
private string _Bar ; 
  Foo ( string bar)
  {
    _Bar = bar ; 
  }
 public string Bar 
 { 
   get { return _Bar ; //more logic here
   } 
   set { _Bar = value ;   //more logic could be added
  }
 }
}

OR

class Foo {
private string _Bar ; 
  Foo ( string bar)
  {
    this.Bar = bar ; 
  }
 public string Bar { 
  get { return _Bar ; //more logic could be added } 
  set { _Bar = value ; //more logic could be added }}
}

编辑:我知道后者允许在其中添加更多逻辑,但由于它而使用它是否合理......

7 个答案:

答案 0 :(得分:6)

无论哪种方式对班级有意义;没有“最佳实践”。

有时您可能希望确保您只执行属性可以执行的相同操作;在这种情况下,使用该属性是有意义的。

有时候你想要做的事情只能在构造函数中完成,这些事情违反了你可以通过属性构造后完成的事情,在这种情况下,使用该字段是有意义的。

答案 1 :(得分:1)

取决于。

当没有副作用时,我更喜欢使用这些属性。但是,有时候设置属性会产生其他副作用,例如事件通知,可能不需要(此时)验证等。在这些情况下,直接设置支持字段是更好的选择。

答案 2 :(得分:1)

这取决于,如果您需要执行公共属性中的逻辑,请使用该方法。如果您只是进行直接分配,那么分配给私人成员就可以了。

答案 3 :(得分:1)

我经常使用这些属性,因为它允许我只在一个地方(属性设置器)编写我的验证。它有助于避免重复代码。

public class Foo
{
   private string _Bar = String.Empty;

   public string Bar
   {
      get { return _Bar; }
      set 
      {
          if (value == null)
             throw new ArgumentNullException("Bar");
          _Bar = value;
      }
   }

   public Foo(string bar)
   {
      Bar = bar;
   }
}

答案 4 :(得分:0)

请阅读Eric Lippert撰写的这篇优秀博客文章:Automatic vs Explicit Properties

  

这是我从C#用户那里得到的一个问题   去年,我得到了一个公平的问题   频繁:

     

用户:使用“常规”显式属性,我倾向于使用私有   直接从内部支持领域   类。当然,用自动   财产,你不能这样做。我的   关注的是,将来,如果我   决定我需要一个明确的属性   无论什么原因,我都离开了   改变班级的选择   实现使用新的私有   现场,或继续经历   属性。我不确定是对的   在这种情况下要做的事情是。

     

你说“无论出于何种原因”,和   这是关键。你的答案   问题将完全取决于   是什么原因导致了这一点   变化

     

如果是有动机的原因   从自动实施改变   要明确实现的属性   属性是改变语义   该属性然后 你应该   评估是否需要语义   从访问该物业时   在课堂上与或相同   与所需的语义不同   从访问该物业时   课外。 [强调我的]

答案 5 :(得分:0)

您的示例有点过于简单,但您的评论“//可以添加更多逻辑”暗示了set属性可能比对私有变量的简单赋值更复杂。

如果已在属性集中编码了相同的逻辑,则不要在构造函数中重复相同的逻辑。这将是不必要的重复代码,并且当逻辑需要改变时可能容易出错,并且对于将来必须维护代码的开发人员来说是一个痛苦的问题。

如果你的set属性在构造函数中有一些不需要/不需要的副作用,比如事件通知,那么你应该将公共代码重构为它自己的方法。构造函数和set属性都可以调用此方法。

你会得到很多“它依赖”的答案,因为,这取决于。其中一些原因将是个人偏好(通常由过去的经验决定,其中某些东西难以维护或有缺陷)。有些原因是每种情况都不同,虽然我们使用代码实现了很多常见的模式和任务,但总是需要有可能不遵循规范,在您的编码解决方案中具有创造性或创新性问题。请记住,我们不编写代码,我们使用代码作为工具编写解决方案。

答案 6 :(得分:0)

我会在我的“依赖”答案中加入一些内容:你试图在确保内部状态保持一致,重复代码和性能之间找到平衡。

我同意Adam P,因为你当前的例子非常简单,这无关紧要。

考虑一个示例,其中只读变量Qux依赖于Bar和另一个成员Baz。 Qux的计算成本相当高,所以你不想动态地执行它 - 这表明存储状态的私有字段,并改变它IFF Bar和Baz的变化。

所以在构造函数中你可以公开设置Bar和Baz,知道Qux将被解析两次,或者将Qux的分辨率推迟到构造函数的结尾(并保存一个Qux解析调用)。

在不太可能改变的相当简单的代码中(例如支持简单私有字段的公共属性),选择一种风格,坚持使用它,并集中精力解决程序中的实际问题。