定义私有字段和 属性 与仅定义 属性
Defining both Private Field and Property vs just Property
遵循 OOP 的最佳实践,是否最好使用以下代码:
class Car {
private Driv driver;
public Driv Driver {
get { return driver; }
set { driver = value; }
}
}
还是这个?
class Car
{
public Driv Driver { get; set; }
}
虽然第二个版本更短,但我觉得我打破了封装概念的主要前提:
EVERY class should keep its privates to itself.
希望答案不要太琐碎。
你的第一个例子是所谓的 Property with a backing field
第二个叫做 Automatic property
。
带有支持字段的 属性 的目的是让您可以控制对私有属性的访问。
所以...例如,如果您想在返回私有字段的值之前进行计算,您可以在带有支持字段的字段中进行计算。
或者假设你有一个汽车对象,时钟上有 10,000
英里......你可能只想使用 Drive
方法增加它的值,并隐藏 setter
的 属性 和支持字段
void Main()
{
var car = new Car();
car.Drive();
Console.WriteLine (car.Miles);
}
public class Car
{
private int miles;
public Car()
{
miles = 10000;
}
public int Miles
{
get
{
return this.miles;
}
}
public void Drive()
{
this.miles += 100;
}
}
真的没有区别。如果用户没有创建私有变量,那么将为私有字段自动生成代码。但是,如果用户希望在 属性 的 getter 或 setter 中执行其他逻辑,则需要声明私有字段。
第二种方法并没有破坏封装。第二种方法是语法糖,使 属性 定义不那么冗长。这种方法的好处是,如果您将来需要修改 getter 或 setter,您已经准备好这样做并且不会破坏 API 契约。
C# 的属性只是一些底层方法和变量的简单语法表示。本质上,编译器会变成:
public int Height { get; set; }
进入:
private int height;
public int getHeight() {return height;}
public int setHeight(int h) {height = h;}
所以,不,你不是在违抗 OOP 封装,而是在语法上简化了它。您还可以执行类似 public int Height {get;}
的操作,这是创建不可变 class 成员的好方法。它只是在没有设置方法的情况下创建 属性,因此只有 class 本身可以更改它。
现在,如果您希望在获取或设置变量时执行其他任务(例如引发事件或更新另一个变量),则只需使用带有支持字段的属性。编译器会变成:
private int height;
public int Height { get {return height;} set {height = value; OnHeightChanged();} }
进入:
private int height;
public int getHeight() {return height;}
public int setHeight(int value) {height = value; OnHeightChanged();}
希望对您有所帮助!
遵循 OOP 的最佳实践,是否最好使用以下代码:
class Car {
private Driv driver;
public Driv Driver {
get { return driver; }
set { driver = value; }
}
}
还是这个?
class Car
{
public Driv Driver { get; set; }
}
虽然第二个版本更短,但我觉得我打破了封装概念的主要前提:
EVERY class should keep its privates to itself.
希望答案不要太琐碎。
你的第一个例子是所谓的 Property with a backing field
第二个叫做 Automatic property
。
带有支持字段的 属性 的目的是让您可以控制对私有属性的访问。
所以...例如,如果您想在返回私有字段的值之前进行计算,您可以在带有支持字段的字段中进行计算。
或者假设你有一个汽车对象,时钟上有 10,000
英里......你可能只想使用 Drive
方法增加它的值,并隐藏 setter
的 属性 和支持字段
void Main()
{
var car = new Car();
car.Drive();
Console.WriteLine (car.Miles);
}
public class Car
{
private int miles;
public Car()
{
miles = 10000;
}
public int Miles
{
get
{
return this.miles;
}
}
public void Drive()
{
this.miles += 100;
}
}
真的没有区别。如果用户没有创建私有变量,那么将为私有字段自动生成代码。但是,如果用户希望在 属性 的 getter 或 setter 中执行其他逻辑,则需要声明私有字段。
第二种方法并没有破坏封装。第二种方法是语法糖,使 属性 定义不那么冗长。这种方法的好处是,如果您将来需要修改 getter 或 setter,您已经准备好这样做并且不会破坏 API 契约。
C# 的属性只是一些底层方法和变量的简单语法表示。本质上,编译器会变成:
public int Height { get; set; }
进入:
private int height;
public int getHeight() {return height;}
public int setHeight(int h) {height = h;}
所以,不,你不是在违抗 OOP 封装,而是在语法上简化了它。您还可以执行类似 public int Height {get;}
的操作,这是创建不可变 class 成员的好方法。它只是在没有设置方法的情况下创建 属性,因此只有 class 本身可以更改它。
现在,如果您希望在获取或设置变量时执行其他任务(例如引发事件或更新另一个变量),则只需使用带有支持字段的属性。编译器会变成:
private int height;
public int Height { get {return height;} set {height = value; OnHeightChanged();} }
进入:
private int height;
public int getHeight() {return height;}
public int setHeight(int value) {height = value; OnHeightChanged();}
希望对您有所帮助!