定义私有字段和属性与仅属性

本文关键字:属性 字段 定义 | 更新日期: 2023-09-27 18:36:01

遵循OOP的最佳实践,拥有以下代码是否更好:

class Car {
    private Driv driver;
    public Driv Driver {
        get { return driver; }
        set { driver = value; }
    }
}

还是这个?

class Car
{
    public Driv Driver { get; set; }
}

虽然第二个版本更短,但我觉得我打破了封装概念的主要前提:

每个类都应该保持自己的私有状态。

希望答案不要太微不足道。

定义私有字段和属性与仅属性

真的没有区别。如果用户没有创建私有变量,则将为私有字段自动生成代码。但是,如果用户希望在属性的 getter 或 setter 中执行其他逻辑,则必须声明私有字段。

你的第一个例子就是所谓的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,您可以这样做,并且不会破坏 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;}的事情,这是创建不可变类成员的好方法。它只是在没有 set 方法的情况下创建属性,因此只有类本身可以更改它。

现在,如果您希望在获取或设置变量时执行其他任务(例如引发事件或更新另一个变量),则只需将属性与支持字段一起使用。编译器将转向:

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();}

希望这有帮助!