私有的设置还是私有成员?

24

我想知道在C#中什么是最佳实践:使用私有/受保护成员和公共的getter,还是使用公共的getter和私有/受保护的setter?

       public int PublicGetPrivateSetter
       {
            get;
            private set;
        }

        private int _privateMember;

        public int PublicGetPrivateMember
        {
            get { return _privateMember; }
        }

我认为在代码中使用私有成员更能明确它是一个私有setter(以命名约定为例)。 另一方面,使用私有setter可选用虚拟(protected),写入更少的代码,减少错误的可能性,并在需要时提供添加副作用的选项。

我没有找到什么被认为是最佳实践,甚至也没有人认为其中一个比另一个更好。从我看到的代码来看,通常80%的时间(我所看到的代码)人们不使用私有setter……我不确定这是因为人们不知道私有setter的存在,还是因为使用私有成员被认为更好。

编辑:

当使用私有成员时,还有其他优点,例如默认值和只读的使用。

7个回答

34

我更喜欢使用自动属性,除非默认实现不符合我的要求。所以在这种情况下,由于自动属性已经满足你的需求,只需要使用它:

public int Foo { get; private set; }

但另一种情况是,如果您想使字段只读(意味着唯一可以设置该字段的地方是在构造函数中)。那么您需要定义备份字段并将其标记为只读,因为自动实现属性不支持此操作:

private readonly int foo;

public int Foo
{
    get { return foo; }
}

使用私有后备字段的另一个好处是属性更改通知器,实现INotifyPropertyChanged接口。在这种情况下,您可能需要限制setter。在这种情况下,我通常有一个私有字段,带有公共属性和私有setter。在setter中,我调用NotifyPropertyChanged事件。 - Adarsha
但如果它是readonly,有没有理由不将其设置为公共成员?(public readonly int foo;) - Roee Gavirel

0

我不知道有什么最佳实践。我知道自动属性主要是为了使代码生成和LINQ相关的事情更加容易。

对于我来说,我会从自动属性开始,如果需要的话再进行重构。根据需要,我可能会像你提到的那样将某些内容更改为虚拟或受保护的,或者重构以使用变量(当我想要重构设置访问器以具有一些逻辑时)。


0

它们是一样的。在第一个例子中,编译器生成了支持存储区。在第二个例子中,您生成了支持存储区。由于实现是类内部的,所以将一个重构为另一个并不是什么大问题。像Resharper这样的工具可以使其变得微不足道。您可能没有看到太多私有setter的原因是它是C# 3.0的功能。


自动实现属性通常是C# 3.0的一个特性。 - Bryan

0

私有setter没有什么问题。在大多数情况下,它与自动属性一起使用,在对象的作用域之外将属性设置为只读。


1
但如果您使用自己的后备字段,则与“readonly”关键字不同。 - Bryan

0
从概念上讲,它并没有改变任何东西。这主要是一种口味问题。
个人而言,我使用私有 setter,因为我很懒,经常使用 propg 代码片段。(propg tab tab)
此外,大多数时候我都会设置脏标志并将事件绑定到这些属性,因此我可能会在一开始就处理其中一部分工作。如果您以后需要添加 setter,那么如果代码从一开始就没有使用该成员,那么更容易做到这一点,因为需要更改的代码量更少。

0

这个问题并没有一个确定的好答案。最好的做法是遵循我们公司的命名规范,如果你独自一人,那就按照你自己喜欢的方式来就可以了。


0
在我看来,没有最佳实践,编译后的代码结果几乎没有什么区别,这取决于你的需求或个人喜好。如果你遵循团队的命名标准并满足要求(例如不需要传播更改通知),那么这就无关紧要了。
私有字段的一个优点是可以在声明的同一位置定义默认值。在自动实现的属性中,如果它不是 null 或类型的默认值,则必须在构造函数中定义默认值。
然而,我仍然喜欢私有 setter。但我们通常不使用自动实现的属性,因为我们的 setter 通常具有更丰富的功能 - 例如属性更新通知、日志记录等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接