13

在 Eclipse 中生成 setter 和 getter 时,选项之一是在类中使用 getter 和 setter,而不是直接访问类成员。这种级别的类内部封装是有用的,还是将一个好主意走得太远了?

DUPE您应该使用类内部的访问器属性,还是只使用类外部的访问器属性?

4

7 回答 7

11

我认为,如果您希望发生潜在的副作用 - 验证、日志记录等,这是一个好主意。(在 C# 中,我希望能够声明一个变量和属性,并说对变量的唯一访问是通过财产。)

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

于 2009-02-25T14:07:14.643 回答
3

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

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

于 2009-02-25T14:08:19.430 回答
3

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

Eric Lippert 有一篇关于Automatic vs. Explicit properties的优秀文章处理了这个问题,尽管角度略有不同。

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

“从类内部,访问这个......属性的所需语义与从外部访问该属性的所需语义不同吗?”

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

于 2009-02-25T16:38:40.427 回答
0

例如,当您有 setter 执行额外操作(例如设置脏标志或通知观察者)时,它很有用。

对于吸气剂,您可以在更改表示时计算一个值,而不是访问一个字段。

于 2009-02-25T14:08:39.693 回答
0

我发现我有时会这样做 - 特别是当我需要或强烈预期我会需要一些登录时,获取或设置(以及围绕它们的验证)成员。

我发现在这些情况下,拥有私有/内部属性确实有帮助。

但我当然不会为任何成员这样做。

最新的 .NET/VS 在这里真的很有帮助,因为您可以这样声明一个属性:

public string SomeProperty
{
get;
set;
}

它有效地创建了幕后的memebr。我知道这对您没有帮助,但我认为这可能会引起您的兴趣:-)

于 2009-02-25T14:08:52.580 回答
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;
        }
    }
}

数据对象.cs:

namespace WpfDatabinding
{
    public class DataObject
    {
        // convert this to a field, and databinding will stop working
        public string Name
        {
            get;
            set;
        }
    }
}
于 2009-02-25T16:30:40.413 回答
0

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

于 2009-03-12T17:36:48.217 回答