什么时候应该使用自己的getter / setter来直接访问成员?

时间:2009-02-25 14:01:43

标签: oop encapsulation

在Eclipse中生成setter和getter时,其中一个选项是使用类中的getter和setter而不是直接访问类成员。这种级别的内部封装是否有用,或者它是一个好主意,一步到位?

DUPE Should you use accessor properties from within the class, or just from outside of the class?

7 个答案:

答案 0 :(得分:11)

我认为如果你想要发生潜在的副作用 - 验证,记录等等,这是一个好主意。(在C#中,我希望能够声明一个变量和属性并且只说 < / em>通过属性访问变量。)

有时您可能会发现需要直接精确设置变量,因为想要副作用。例如,您可能需要将两个变量设置在一起,“之前”和“之后”状态都有效,但单独设置任一属性都会使验证爆炸。

答案 1 :(得分:3)

如果允许派生类重新定义getter,那么它会很有用。因此,即使从课堂内部使用getter也可以保持设计的可扩展性。

在我看来,这是需要在编码指南中定义的内容。

答案 2 :(得分:3)

简短的回答是“它取决于”:)

Eric Lippert在Automatic vs. Explicit properties上有一篇关于这个问题的优秀文章,虽然角度略有不同。

基本上,您需要问的问题是:

  

“从类中,[是]访问此属性所需的语义不同于从外部访问属性所需的语义?”

如果语义相同,则您的类应使用自己的属性。如果语义不同,您的类将需要直接操作支持字段。

答案 3 :(得分:0)

例如,如果您有安装程序执行额外的操作,例如设置脏标志或通知观察者,那么它很有用。

对于getter,您可以在更改表示时不是访问字段来计算值。

答案 4 :(得分:0)

我发现我有时会这样做 - 特别是当我需要时,或者强烈预期我会要求时,一些人会在成员的环境中获取或设置(以及围绕它们进行验证)。

我发现拥有私有/内部属性确实有助于这些情况。

但我当然不会为任何一个人做这件事。

最新的.NET / VS真的有帮助,因为您可以声明属性:

public string SomeProperty
{
get;
set;
}

它有效地创造了幕后的memebr。我知道这对你没有帮助,但我认为它可能有一些兴趣: - )

答案 5 :(得分:0)

如果您希望此成员可以通过Winform或WPF进行数据绑定,我相信您需要将其声明为属性。我有95%的积极性,数据绑定需要一个属性(getter / setting语法)。我有一个小的wpf解决方案来演示这个,但我没有看到在这里附加它的方法。

以下是代码:(使用VS 2008 SP1构建,目标是.net 3.5 - 我使用了WPF项目)。 WPF项目中有2个项目,主窗口(window1)和我们正在测试的对象(DataObject) 窗口上有一个标签,它与数据对象实例中的Name属性进行数据绑定。如果将Name属性转换为字段(删除getter / setter),则数据绑定将停止工作。

Window1.xaml:

<Window x:Class="WpfDatabinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
    <Label Name ="Label1" Height="28" Margin="12,24,37,0" VerticalAlignment="Top" Content="{Binding Name}"></Label>
</Grid>

Window1.xaml.cs

using System;
using System.Windows;

namespace WpfDatabinding
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private DataObject ADataObject;

        public Window1()
        {
            InitializeComponent();
            this.ADataObject = new DataObject();
            this.ADataObject.Name = "Hello!";
            this.DataContext = this.ADataObject;
        }
    }
}

namespace WpfDatabinding
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private DataObject ADataObject;

        public Window1()
        {
            InitializeComponent();
            this.ADataObject = new DataObject();
            this.ADataObject.Name = "Hello!";
            this.DataContext = this.ADataObject;
        }
    }
}

DataObject.cs:

namespace WpfDatabinding
{
    public class DataObject
    {
        // convert this to a field, and databinding will stop working
        public string Name
        {
            get;
            set;
        }
    }
}

答案 6 :(得分:0)

当您需要扩展类的getter / setter行为时,封装字段(getter / setter而不是直接成员访问)非常有用。 然而,在继承中,如果它的子类不应该知道它的私有东西,那么保留类的内部是有意义的。因此,有时该字段对于类的实现是私有的,因此即使子类也不知道它。