我应该公开我的类的属性吗?

时间:2013-03-24 14:22:09

标签: c# java c++ oop

在我的所有学习期间,我了解到,当我想让用户访问内部属性时,我不应该直接访问该属性,而是通过get / set方法提供访问权限,例如:

class myClass
{
    private int x;

    public void SetX (int x)
    {
        this.x = x;
    }

    public int GetX ()
    {
        return this.x
    }
}

因为它提供了额外的好处,允许程序员在不影响用户的情况下更容易地更改引擎,更容易解决问题,并提供更多选项来检查输入的有效性。

然而,自从我开始用C#学习和写作以来,我注意到大多数“语言本地”的类暴露了它们的属性,例如,设置/获取矩形的位置或大小({{3您可以直接访问XYWidthHeight属性。

  • 我看到暴露属性的唯一好处是代码更简单一些。暴露财产还有其他好处吗?

  • 我应该何时公开属性,何时不应该公开?

4 个答案:

答案 0 :(得分:2)

你混淆了属性和字段。在C#中,属性可以像公共字段一样使用,但在内部调用它们的get / set方法。例如,具有属性的类看起来像这样:

class MyClass
{
    // Field, direct access to the internal representation
    private int x; 

    // Property, access via methods, but syntax like field access
    public int X {
        get { return this.x; } // generates a get-method "int get_X()"
        set { this.x = value; } // generates a set-method "void set_X(int value)"
    }
}

当您现在设置属性X时, myClass.X = 42 ,编译器会将其转换为 myClass.set_X(42) ,它会调用在 set 块。 Field-like语法只是为了方便起见。

所以你应该更喜欢暴露set / get-methods。只是在C#中,这样做的首选方法是通过Properties,它抽象出这些方法的实际调用,并允许你像字段一样使用它们。

答案 1 :(得分:1)

所以基本上,你的问题是属性与公共变量。什么时候用?

阅读this Post,包括评论。

整个讨论的快速摘要:

  • 反射在变量与属性上的工作方式不同,所以如果依赖于反射,则 它更容易使用所有属性。
  • 您无法对变量进行数据绑定。
  • 将变量更改为属性是一个重大变化。

暴露数据成员的琐碎属性实现是很多代码,没有或只有很少的收益,只有合理的理由可以是:

  • 提供对由于某种原因无法声明为const的成员var的只读访问

  • 如果您正在编写一个供某些第三方使用的组件,并且有可能必须更换该组件而不需要这些用户进行重建(将公共成员变量更改为属性会破坏界面,因此需要重建。)

此外,在属性中包装公共字段有两个原因 - 一个是您不能在不破坏二进制兼容性的情况下更改它。二是你无法绑定到字段。

Reflection code against fields looks very different from reflection code against 
properties (FieldInfo vs. PropertyInfo for starters). So even if you can 
recompile against the new binary, if you use reflection on that field 
you're hosed.

答案 2 :(得分:0)

在C#中,您使用属性而不是getter / setter方法,因为它们提供相同的功能。请注意字段!= properties。请参阅MSDN: Properties

答案 3 :(得分:0)

正如您所说,不直接访问您的变量的优点是您可以更改实现而无需对您的类的用户进行任何更改。在面向对象编程方面,我认为这是一件很重要的事情。

此外,使用属性,您仍然可以影响“获取”或“设置”的工作。这在某些情况下很有用。