6

目前我正在考虑 C# 中的数据封装,我有点困惑。几年前,当我开始学习用 C++ 编程时,我的教授告诉我:-“创建一个类并隐藏它的数据成员,因此不能直接从外部对其进行操作”

示例:您正在解析一个 XML 文件并将解析后的数据存储到解析器类中的一些数据成员中。

现在,当我在看 C# 时。你有那里的属性。此功能使类的内部状态/内部数据对外部可见。不再有封装。对?

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

从我的角度来看,将数据成员设为公共或拥有公共属性之间没有区别,公共属性具有 getter 和 setter,您可以在其中传递私有数据成员。

有人可以解释一下吗?

谢谢

4

7 回答 7

16

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

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

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

请记住,在 .NET 中,Property 实际上只是 2 种方法的更简洁的语法 - 一种方法用于属性获取部分,一种方法用于属性设置部分。它提供了与 C++ 中的一对方法相同的所有封装,但(可以说)使用更好的语法。

于 2010-09-17T22:04:44.130 回答
2

好吧,乍一看,房产并不是你所认为的狂野西部。OOP 的不幸事实是,您的许多方法都是 getter 和 setter,而属性只是使这更容易编写的一种方式。您还可以控制您希望该物业允许某人做什么。您可以使属性可读但不可写,如下所示:

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

或者正如 Reed 所提到的,您可以让您的 set 方法对任何复杂性进行转换或检查。例如像

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

您通常拥有从封装中获得的所有价值,并带有一些语法糖以使一些常见任务更容易。您可以做与其他语言中的属性相同的事情,只是看起来不同。

于 2010-09-17T22:09:33.727 回答
1

属性的好处是,稍后,您可以决定向 setter 方法添加验证等,或者让 getter 方法进行一些计算或缓存,并且已经调用您的属性的代码都不需要更改 - 因为类'界面保持稳定

于 2010-09-17T22:04:09.103 回答
1

如果需要,仍然存在数据封装。封装数据并不是要对类的客户端隐藏它或使其不可访问,而是要确保接口和内部对象状态的一致性。

假设您有一个表示变速汽车的对象和一个用于设置速度的属性。您可能知道应该在速度间隔之间换档,这就是封装的用武之地。

您可以在 C# 中使用属性 getter 和 setter,而不是简单地将属性公开,从而允许在没有任何验证的情况下公开访问:

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

虽然这个例子不一定是可编译的,但我相信你会明白我的意思。

于 2010-09-17T22:08:06.070 回答
1

You may be missing the fact that you don't have to have properties to correspond to all class member fields. You can decide which properties to add to your class, and whether or not they will be accessible outside of the class.

于 2010-09-17T23:28:00.060 回答
0

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

于 2010-09-17T23:23:00.617 回答
0

The very first attempt of using property to encapsulate the value is get;set; But C# provide more advanced feature to enrich functions inside get and set to make the property read-only, write-only or with certain conditions. For example, to set the value as

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

will be better than using:

public readonly string Temp;
于 2018-02-18T00:37:53.057 回答