类什么时候应该使用自己的 getter/setter,而不是直接访问成员?
-
06-09-2019 - |
题
在 Eclipse 中生成 setter 和 getter 时,选项之一是在类中使用 getter 和 setter,而不是直接访问类成员。这种级别的类内部封装是否有用,或者是否是一个好主意走得太远了?
解决方案
我认为这是一个好主意,如果你想要的潜在副作用发生 - 验证,日志等(在C#中,我想能够声明一个变量和财产,并说,仅的访问变量是通过属性。)
有时你可能会发现你需要设置变量直接恰恰是因为你的不的想要的副作用。例如,您可能需要设置两个变量在一起,无论是“之前”和“之后”状态是有效的,但设置任一属性单独将使验证炸毁。
其他提示
这可能是有用的,如果你让派生类重新定义你的干将。因此,使用干将甚至从类内部将让您的设计可扩展性。
在我看来,这是一件需要在编码规则进行定义。
简短的答案是“这取决于”:)
埃里克·利珀特(Eric Lippert)有一篇关于 自动对比显式属性 尽管角度略有不同,但它处理了这个问题。
本质上,您需要问的问题是:
“从类内部,[是]访问这个所需的语义......属性与从外部访问属性所需的语义不同吗?”
如果语义相同,您的类应该使用自己的属性。如果语义不同,您的类将需要直接操作支持字段。
当你制定者该做的,如设置脏标志或通知观察员额外的动作它是有用的。
有关的吸气剂可能你的而不是访问的字段,当你改变表示计算一个值。
当需要扩展类的吸气/设定器的行为,它是已封装字段(getter / setter方法,而不是直接成员访问)是有用的。 然而,在继承,这是conceptualy有趣保护你的类的内件,如果它的子类不应该知道其私人的东西。所以,有时候领域是私人的类的实现,因此,即使子类都没有意识到这一点。
我发现,我这样做,在时间 - 特别是当我需要,或强烈预期,我会要求,一些登录各地获取或成员的设定(和他们周围的验证)。
我发现有私人/内部属性在这种情况下确实有帮助。
但我肯定不会对任何memeber做到这一点。
最新的.NET / VS真正帮助在这里,你可以声明一个属性为这样的:
public string SomeProperty
{
get;
set;
}
和它有效地创建场景后面的memebr。我知道,不帮你,但我认为这可能是一些利益: - )
如果你想为这个成员无论以任何的Winform或WPF是databindable,我相信,你需要把它声明为一个属性。我大约95%的肯定,绑定需要一个属性(的getter /设置语法)。我有一个演示这个小WPF的解决方案,但我不明白的方式在这里附上。
下面的代码:(与VS 2008 SP1内置,靶向.NET 3.5 - I中使用的WPF项目)。 有2项在WPF项目中,在主窗口(窗口1),和我们正在测试的对象(数据对象) 有一个数据绑定到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;
}
}
}