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

时间:2016-02-24 18:33:09

标签: c# oop encapsulation

遵循OOP的最佳做法,拥有此代码是否更好:

class Car {

    private Driv driver;

    public Driv Driver {

        get { return driver; }

        set { driver = value; }
    }

}

还是这个?

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

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

  

每个班级都应该保持自己的私密性。

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

4 个答案:

答案 0 :(得分:3)

您的第一个例子是所谓的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;
    }
}

答案 1 :(得分:3)

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

答案 2 :(得分:1)

你没有打破第二种方法的封装。第二种方法是语法糖,使属性定义更简洁。这种方法的好处是,将来如果你需要修改getter或setter,你就可以这样做,并且不会违反API合同。

答案 3 :(得分:0)

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

希望这有帮助!