【问题标题】:Encapsulating correctly the property setter of base class正确封装基类的属性设置器
【发布时间】:2017-09-05 06:43:52
【问题描述】:

我对在基类中封装属性设置器有点困惑。

  • 假设其中一些属性是在 base 构造函数中设置的,那么 setter 应该是私有的还是受保护的?

  • 假设其中一些属性在 child 构造函数中设置,设置器应该是私有的还是受保护的?

为了更清楚,这里是一个具体的案例:

public abstract class Records
{
    public string Date { get; protected set; }
    public string Source { get; protected set; }
    public string Type { get; protected set; }
    public int Value { get; protected set; }

    protected Records(string type, string source, int value)
    {
        Type = type;
        Source = source;
        Value = value;
        Date = DateTime.Now.ToString("hh.mm.ss.ffffff");
    }
}

public class NewDocumentRecord : Records
{
    public NewDocumentRecord(string source, int value)
        : base(ContentTypesString.DocumentNew, source, value)
    {
        Source = source;
        Value = value;
    }
}

【问题讨论】:

    标签: c# oop properties encapsulation


    【解决方案1】:

    一般来说,很难为基类中的受保护设置器提供案例:如果一个属性属于基类,那么控制它的逻辑也属于基类。

    假设其中一些属性是在基本构造函数中设置的,那么设置器应该是私有的还是受保护的?

    假设属性在构造函数中设置一次,并且不再更改,那么 setter 应该是私有的,或者根本不应该有 setter(C# 6 或更高版本)。

    public string Date { get; }
    

    假设其中一些属性是在子构造函数中设置的,那么设置器应该是私有的还是受保护的?

    如果属性是在基类中声明的,那么设置其初始值的任务也应该是基类构造函数的一部分。最好的做法是将值从子构造函数传递给基构造函数,让它在将值设置到属性之前验证数据。

    这并不意味着你不应该让子类修改在基类中声明的属性,只是你应该避免让自动生成的 setter 受到保护。如果您需要使属性只能由子类修改,请为它们提供受保护的方法。

    【讨论】:

    • 我在这个解决方案中使用了 C#5。如果我理解正确,在上面的例子中,我的子类应该有 public MyClass(string source, int value) : base(ContentTypesString.DocumentNew, source, value) {} ?与私人二传手?
    • @YthioCsi 是的,完全正确。
    【解决方案2】:

    如果您只想在基类中设置属性并将其隐藏在子类中,您应该将 setter 设为私有。

    如果您只想在基础 ahd 子类中设置值,则应使其受到保护。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-29
      • 1970-01-01
      • 2014-09-10
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多