C# 成员变量和成员属性之间的差异?
有些情况下,我会在类的顶部声明成员变量,然后还声明一个属性来访问或设置该成员变量,但我会问自己,如果该属性只从类内部访问和设置,而不是从其他地方访问和设置,那么该属性是否必要,那么,使用属性访问和设置成员变量而不是直接对成员变量本身进行访问和设置有什么好处呢。以下是一个例子:C# 成员变量和成员属性之间的差异?,c#,oop,C#,Oop,有些情况下,我会在类的顶部声明成员变量,然后还声明一个属性来访问或设置该成员变量,但我会问自己,如果该属性只从类内部访问和设置,而不是从其他地方访问和设置,那么该属性是否必要,那么,使用属性访问和设置成员变量而不是直接对成员变量本身进行访问和设置有什么好处呢。以下是一个例子: public class Car { int speed; //Is this sufficient enough if Car will only set and get it. public Car
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,我将不得不在使用它的任何地方将Speed更改为spd,但是,如果我使用Speed之类的属性来设置和获取速度,我只需要在属性的get和set中将Speed更改为spd,因此,在我的multilplyspeed方法中,上面这样的东西。Speed=this.Speed+this.Speed+this.Speed不会中断。有一件事您忘了提到,当您扩展类时,属性将帮助您。 如果您的类设计正确,那么基类中的变量应该是
private
。没有实际属性public
properties。您将无法从扩展类中访问这些私有变量。我们谈论的是公开与私人,我不包括受保护的原因:)
只是一些值得一提的注意事项:
- 扩展类时属性助手
- 属性使代码更具可读性(此外还有this.private变量vs on PublicPropertyVariableName)
- 属性可以确保只读、私有集、公共GET等(其他程序员更容易阅读)。考虑一个标识符需要公共获取但私有集合 的情况。
- 就我个人而言,太多的get/set似乎使代码复杂化,使代码可读性降低,太多多余的不必要的语法
- 继承/扩展到扩展类不允许继承私有变量,答案是属性。(这里再次没有提到受保护,这是一个不同的故事)
- 对我来说,即使类有一个私有变量,我的类方法仍然使用该属性来访问或使用该私有变量
- 不要忘记验证,它使验证变得更容易,尤其是在可读性方面
这些只是一些常见的事情(虽然大部分都是我的2美分)。像验证这样的事情可以在一个地方解决。成员是封装的,您需要担心验证和其他类中的事情
在您当前的场景中,这并没有真正的区别,但是当您需要更改变量或需要添加行为时,使用属性会更容易,因为您只有一个地方需要更改它。如果变量是
私有的
,我通常不会为它创建属性。如果它以任何方式暴露在类型之外,出于不同的原因,我总是通过属性暴露它:
- 今天可能没有必要,但如果以后有必要,这将是一个突破性的变化
- 数据绑定只能在属性上工作,不能在字段上工作(我想,不是一个大的数据绑定用户)
- 它允许在访问值时插入验证、日志记录和断点
响应于您更新的代码示例:在代码设计中有许多事情需要考虑。
- 可读性与速度
- “原子性”
- 其他副作用
speed
,该字段通过属性speed
公开。如果方法multilyspeed
需要对该值执行多次更新,则这些中间值将在计算过程中的不同时间通过Speed
属性可用。无论是直接更新字段还是通过属性更新字段,都是如此。在这种情况下,最好先将值放入局部变量,将其用于计算,并在完成后将该变量的值赋回属性
最后,还有其他副作用。可能是更改Speed
的值会引发事件(例如SpeedChanged
)。在这种情况下,在计算完成之前不进行更新可能也是一个好主意
我喜欢将财产视为合同,将现场视为实施。任何需要该值的人(我类型的核心除外)都应该使用该合同。只有在有充分理由绕过合同的情况下,才能依靠执行
是的,如果您将对字段的访问封装在属性中,那么自然地更改字段的名称将需要更少的更新(而且字段的名称也可能变得不那么重要)
我希望这是有道理的,而且不要离题太多;) 它不添加缓存,但允许一致的接口 想象一下,你必须在将来通过增加一个常数来控制速度。在属性允许这种操作的情况下,使用成员变量将很困难 也
public class Car
{
public Car(int initialSpeed)
{
Speed = initialSpeed;
}
public int Speed { get; set; }
public void MultiplySpeed(int multiply)
{
Speed *= multiply;
}
}
public int Speed { get; private set; }