2010-09-17 92 views
5

当前我正在考虑在C#中进行数据封装,我有点困惑。 多年前,当我开始学习用C++编程,我的教授告诉我: - “创建一个类,并隐藏数据成员,所以不能直接从外部操纵”在C#中使用属性进行数据封装

例: 你是解析XML文件并将解析的数据存储到解析器类中的一些数据成员中。

现在,当我在看C#时。你有那里的属性。该功能使得一个类的内部状态/内部数据可见。 没有封装了。对?

private string _mystring; 
public string MyString 
{ 
    get {return _mystring;} 
    set {_mystring = value;} 
} 

从我的角度来看存在使得数据成员的公共或具有公共属性,它有getter和setter,在那里你通过传递您的私人数据成员之间没有什么区别。

有人能解释我吗?

感谢

回答

13

私有数据由属性本身封装。访问数据的唯一方法是通过该属性。

在您上面的情况中,没有什么理由使用该属性。但是,如果以后需要添加一些验证,可以在不破坏API,即::

private string _mystring; 
public string MyString 
{ 
    get {return _mystring;} 
    set 
    { 
     if (IsAcceptableInput(value)) 
     _mystring = value; 
    } 
} 

记住一个属性,在.NET中,真的只是2种方法更清晰的语法 - 一个方法属性获取部分,一个属性集部分。它提供了所有与C++中的一对方法相同的封装,但是(可以说)更好的使用语法。

+0

非常感谢。这清楚地表明了一些事情。 – Ferhat 2010-09-17 22:09:51

0

性能的好处是,以后,你可以决定验证等添加到setter方法,或使getter方法做一些计算或高速缓存,并没有代码已经调用你财产将需要改变 - 因为类的接口保持稳定

1

还有数据封装,如果你需要它。封装数据并不是将它从类的客户端隐藏起来或使其无法访问,而是关于确保一致的接口和内部对象状态。

比方说,你有一个对象代表一个换档车和一个属性来设置速度。您可能知道您应该在速度间隔之间切换齿轮,所以这就是封装进来的地方。因此,您可以在C#中使用属性获取器和设置器,而不是简单地将该属性公开,从而允许公共访问,而不必进行任何验证。

class StickShiftCar : Car 
{ 
    public int MilesPerHour 
    { 
     get {return this._milesPerHour;} 

     set 
     { 
      if (vaule < 20) 
       this._gearPosition = 1; 
      else if (value > 30) 
       this._gearPosition = 2; 
      ... 
      ... 
      this._milesPerHour = value; 
    } 
} 

虽然这个例子不一定是可编译的,但我相信你会发现我的漂移。

2

那么,所以属性不是狂野的西部,你要让他们乍一看。 OOP的不幸事实是,你的很多方法都是getter和setter,而属性只是一种简化写操作的方法。你也可以控制你希望房产允许某人做什么。你可以做一个财产可读但是不能写,就像这样:

private string _mystring; 
public string MyString 
{ 
    get {return _mystring;} 
} 

或由励提到的,你可以有你的一套方法做了改造或复杂性的任何金额的检查。比如像

private long myPrime; 
public long Prime { 
    get { return myPrime; } 
    set { 
    if (prime(value) { 
     myPrime = prime; 
    } 
    else { 
     //throw an error or do nothing 
    } 
    } 
} 

你一般都从封装得到的,有些语法糖使一些常见任务更容易的价值。你可以在其他语言中做同样的事情,它看起来不一样。

+1

+1我只是在输入相同的东西:) – skajfes 2010-09-17 22:11:33

0

再深入一点,你的教授为什么要告诉你封装?仅仅因为它是适当的面向对象设计?为什么这是正确的方式?编程语言和范例只是一种应对让处理器以可理解的方式运行我们的代码的复杂性的方式。有两个代码阅读器,机器和人类。该机器将高兴地从内存空间中的任何地址加载数据或转移到该地址。另一方面,我们人类喜欢思考“事物”。我们的大脑处理具有属性或执行动作的“事物”。狮子会吃掉你,矛可以为你辩护,狮子是毛茸茸的,矛是尖的。所以我们可以理解程序是否被模拟为“事物”。属性应该模拟事物的属性,方法应该模拟事物动作。在实践中,它可能变得相当模糊,一切都不能被模拟为真实的世界行为,但如果做得好,努力做到可以使程序易于理解。

0

您可能会错过一个事实,即您不必具有与所有类成员字段相对应的属性。您可以决定将哪些属性添加到班级中,以及是否可以在班级以外访问。

0

使用property来封装值的第一次尝试是get; set; 但是C#提供了更多的高级功能来丰富get和set中的函数,使属性成为只读,只写或某些条件。 例如,以该值作为

private string temp; 
public string temp 
{ 
    get 
    { 
     return temp; 
    } 
} 

设置会比使用更好的:

public readonly string Temp;