成员变量和成员属性之间的区别?

在某些情况下,我在我的类顶部声明成员变量,然后声明一个属性来访问或设置该成员变量,但我问自己,如果该变量只是从内部访问和设置,那么该属性是否必要这个类而不是其他,所以使用属性访问和设置成员变量的优点是什么,而不是直接对成员变量本身进行操作。 这是一个例子:

public class Car { int speed; //Is this sufficient enough if Car will only set and get it. public Car(int initialSpeed) { speed = initialSpeed; } //Is this actually necessary, is it only for setting and getting the member //variable or does it add some benefit to it, such as caching and if so, //how does caching work with properties. public int Speed { get{return speed;} set{speed = value;} } //Which is better? public void MultiplySpeed(int multiply) { speed = speed * multiply; //Line 1 this.Speed = this.Speed * multiply; //Line 2 //Change speed value many times speed = speed + speed + speed; speed = speed * speed; speed = speed / 3; speed = speed - 4; } } 

在上面,如果我没有设置Speed属性并获得变速,我决定将int speed更改为int spd,我将不得不将速度改为spd,无论它在哪里使用,但是,如果我使用一个属性,比如Speed来设置和获取速度,我只需要在属性的get和set中改变spd的速度,所以在我的MutilplySpeed方法中,像上面这样的东西.Speed = this.Speed + this.Speed +这个。速度不会破。

如果变量是private ,我通常不会为它创建属性。 如果它以任何方式暴露在类型之外,我总是通过一个属性暴露它出于不同的原因:

  • 今天可能没有必要,但如果有必要,以后它就是一个突破性的变化
  • 数据绑定仅适用于属性,而不适用于字段(我认为,不是大型数据绑定用户)
  • 它允许在访问值时插入validation,日志记录和断点

此外,如果字段是通过属性公开的,我总是通过属性访问它,即使在类中也是如此。

更新
为了响应您更新的代码示例:此处的代码设计需要考虑很多事项。

  • 可读性与速度
  • “primefaces性”
  • 其他副作用

一个典型的建议(我发现非常好)是“为了清晰起见,为性能测试”。 这意味着当您编写代码时,首先要考虑的是代码在查看代码时是否清楚。 这通常(但并非总是)比代码的原始速度更重要。 在确定获得它的位置时写入速度优化。 访问一个属性比直接读取字段要慢一些,但在大多数情况下,差异可以忽略不计(如果可以测量的话)。

primefaces性可能是个问题。 鉴于您的代码示例,我们有现场speed ,通过属性Speed公开。 如果MultiplySpeed方法需要对该值执行多次更新,那么在计算过程中,这些中间值将在不同时间通过Speed属性提供。 无论您是直接更新字段还是通过属性更新字段,都是如此。 在这种情况下,最好先将值放入局部变量,将其用于计算,并在完成后将该变量的值赋回属性。

最后,其他副作用。 可能是更改Speed的值应该引发一个事件(例如SpeedChanged )。 在这种情况下,在计算完成之前不进行更新也是一个好主意。

我喜欢将房产视为合同 ,将领域视为实施 。 需要该值的任何人(除了我的类型的核心)都应该使用合同。 只有在有充分理由绕过合同时才应依赖实施。

是的,如果您封装了对属性中字段的访问权限,那么自然地更改字段的名称将需要更少的更新(并且可能还有字段的名称变得不那么重要)。

我希望这是有道理的,而且不是太偏离主题;)

我同意弗雷德里克的回答。 有一件事使得遵循他的建议稍微减少工作就是使用自动属性。 这些只是自动生成标准getter / setter逻辑的属性。 您没有得到任何validation,但您可以随后用标准的自动属性替换自动属性。 这种替换不是一个突破性的变化。

在这里,我用自动属性替换了示例中的Speed属性。 请注意,成员变量消失,您的类必须通过属性访问它。

 public class Car { public Car(int initialSpeed) { Speed = initialSpeed; } public int Speed { get; set; } public void MultiplySpeed(int multiply) { Speed *= multiply; } } 

您还可以使用另一种名为“get with private set”的风格。 这意味着getter是公共的,但setter是私有的。 你这样定义:

  public int Speed { get; private set; } 

关于你的问题this. 前缀,它通常是无关紧要的。 唯一重要的是你定义了一个与成员变量同名的方法参数或局部变量。 然后,您可以使用this来访问成员变量。

像validation这样的东西可以在一个地方覆盖。 该成员是封装的,您需要担心validation和其他类的其他事情。

在您当前的场景中,它并没有真正有所作为,但是当您需要更改变量或需要添加行为时,使用属性会更容易,因为您只有一个位置需要更改它。

它不会添加缓存,但它确实允许一致的界面。

想象一下,你必须通过在将来添加常量来提高速度。 使用成员变量将很困难,因为属性允许这种操作。

同样在类的内部,您应该再次访问该属性以保持一致性(想象一下您有一个直接访问成员变量的类的上述场景)。

我所知道的唯一真正原因是如果从assembly体外部访问该区域。 在这种情况下,如果您想为该字段添加灯光function(可能设置脏标志或validation更改),您必须将其更改为一个属性,该属性会更改调用程序集查看它的方式,这也需要重建。 在极少数情况下,您可能会发现您无法控制该程序集,那么您就会遇到问题。

不要让OO狂热者告诉你使用公共领域是错误的,尽管我可能同意自动属性使得这个论点有点没有实际意义。

事实是,如果没有额外的逻辑,公开声明的字段和具有私有后备存储的公共属性之间没有太大区别。 话虽如此,仍然认为使用属性是最佳做法。

在每个人都向我推断可扩展性之前,请记住,如果以后需要添加function,可以使用属性保留名称,并为后备存储引入新名称,这样就不会发生重大变化。

有一件事你忘了提及,属性将帮助你扩展你的课程。 如果您的类设计得当,基类中的变量应该是private 。 没有实际属性的public属性。 您无法从扩展类中访问这些私有变量。 我们正在谈论公共与私人,我不包括受保护的原因:)。

只是值得一提的一些注意事项:

  • 扩展类时的属性辅助
  • 我的属性使代码更具可读性(另外this.privateVariable verson PublicPropertyVariableName)
  • 属性可以确保只读,私有集,公共获取等(对其他程序员来说更具可读性)。 考虑一个IDentifier需要公共获取而非私有集合的情况
  • 就个人而言,太多的获取/设置似乎使代码复杂化,使代码可读性降低,太多额外的不必要的语法
  • inheritance/扩展到扩展类不允许你inheritance私有变量,属性就是答案。 (再次没有提到受保护的,这是一个不同的故事)
  • 对我来说,即使该类有一个私有变量,我的类方法仍然使用该属性来访问或使用该私有变量
  • 不要忘记validation,这样可以更容易地validation特别是可读性。

这些只是一些常见的事情(我的大部分都是2美分)。

在我看来,语言设计被打破了。 不应该有两种方法来处理那么多语义重叠的事情。 属性/字段应该无缝地提供两种方法的好处,具体取决于它们的使用方式。 如果程序最少使用属性function,则它们的行为应与字段相同。 此外,不需要声明空的get; 并设定; 这种情况下的方法。 这些差异让我觉得是人为的。

这是一门很棒的语言; 并且在很大程度上非常干净。 这并不意味着它不应该在“下一次”改进。