Search code examples
c#ooppropertiesencapsulation

Encapsulating correctly the property setter of base class


I'm a bit confused with encapsulation of properties setter in base class.

  • Supposing some of those properties are set in base constructor, the setter should be private or protected ?

  • Supposing some of those properties are set in child constructor, the setter should be private or protected ?

In order to be clearer, here is a concrete case :

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;
    }
}

Solution

  • Generally, it is very hard to make a case for a protected setter in the base class: if a property belongs in the base class, the logic that controls it belongs in the base class as well.

    Supposing some of those properties are set in base constructor, the setter should be private or protected?

    Assuming that the property is set once in the constructor, and never changes again, the setter should be private, or there should be no setter at all (C# 6 or later).

    public string Date { get; }
    

    Supposing some of those properties are set in child constructor, the setter should be private or protected?

    If the property is declared in the base class, the task of setting its initial value should be part of base class constructor as well. The best course of action is to pass the value from child constructor to base constructor, letting it validate the data prior to setting the value into the property.

    This does not mean that you should never let subclasses modify properties declared in the base class, only that you should avoid making auto-generated setters protected. If you need to make a property modifiable only by subclasses, provide them a protected method to do so.