C#构造函数使用私有/公共字段

class Student { private string firstName; public string FirstName { get { return firstName; } set { firstName = value; // Possible logical checks may be implemented here in the future } } public Student (firstName) { this.firstName = firstName; // Option 1 // Or FirstName = firstName; // Option 2 } } 

哪两条线更标准?

我们在构造函数中使用私有成员还是公共成员?

这取决于…通常在您的示例中未包含的内容中。 首先,您的整个房产可以缩短为自动实施的房产:

 public string FirstName { get; set; } 

在这种情况下,这会使问题没有实际意义。 除此之外,问题归结为属性中可能存在哪种逻辑(现在或将来)以及构造函数是否需要调用该逻辑。

例如,属性是否在内部检查所需的值或执行其他一些validation? 像这样的东西:

 private string firstName; public string FirstName { get { return firstName; } set { if (string.IsNullOrWhiteSpace(value)) throw new ArgumentNullException("FirstName"); firstName = value; } } 

在这种情况下,您希望构造函数使用属性而不是支持字段,以便在构造对象时应用逻辑。

相反,您可能具有仅在访问setter时才使用的逻辑,而在构造对象时则不会。 在我的脑海中,一个例子可能是一个维护位置信息的对象。 它可能有一个Address属性和一个Coordinates属性,每当其中一个更改时,就会有一个后端进程来对新值进行地理定位并更新另一个。 但是,您可能有一个接受这两者的构造函数(可能在从数据库重新构建现有位置时),并且在构造期间执行地理定位是没有意义的。 在这种情况下,您将设置支持字段而不是属性。

由于缺乏令人信服的理由不使用这些属性,我通常更喜欢使用它们而不是支持字段。 仅仅因为逻辑可能会在以后所有访问者都应该使用的属性中添加。 我还发现这些属性更有可能比支持字段具有更有意义的名称(例如, FirstName_firstName更具可读性/有意义),因此首选是保持代码的其余部分尽可能可读并且更喜欢可读的名字。

你可以选择3

  public string FirstName {get; set;} public Student (firstName) { FirstName = firstName; } 

这是一种风格的选择并不重要。 就个人而言,我使用公共属性名称,因为我喜欢使用自动属性,在这种情况下,这是唯一的选择。 使用公共属性可以保持我的代码一致。

当我写POCO(普通旧CLR对象)时,事情是微不足道的,我采用这种方法:

 public class POCO { public POCO() { Name = "Moo-Juice"; } public string Name { get; set; } } 

在我真正需要成员变量的非平凡情况下,我用_前缀(这有助于intellisense,相信我 – 并允许你区分成员和本地人):

 public class NonTrivial { private string _name; public NonTrivial() { _name = "Jon Skeet"; // He is non-trivial } } 

这样我就可以避免污染我的代码this. 到处。

这取决于:

  private string firstName; public string FirstName { get { return firstName; } set { firstName = (value=="mycheck")?"default":value; } } 

如果您的财产有一些validation,那么您应该去:

  public Student (firstName) { FirstName = firstName; } 

最常见的是使用该属性,但这是一个选择问题。

特别是在这种情况下,您应该使用自动属性:

 public string FirstName { get; set; } 

编译器会自动添加支持字段。

您也可以选择不添加参数构造函数,因为自C#3.5(IIRC)以来,您可以使用自动初始化程序:

 new Studant() { FirstName = "John Doe" } 

它调用构造函数,并将属性设置为一行。

总的来说,我倾向于只为它真正依赖的东西请求一个构造函数参数(参见: dependency injection ),并且在需要它们之前让并不总是需要它们,比如在持久化之前进行validation。