This is an idiom I have noticed in a C# codebase which I have been working on recently:
class Base
{
private readonly MemberClass _memberVariable;
public Base(MemberClass memberValue)
{
_memberVariable = memberValue;
}
// methods accessing memberVariable...
}
class Derived : Base
{
private readonly MemberClass _memberVariable;
public Derived(MemberClass memberValue) : base(memberValue)
{
_memberVariable = memberValue;
}
// methods accessing memberVariable...
}
Both the base class and its derived class have a member variable which is intialised in their respective constructors, but instead of declaring the member as protected
in the base class and having it available in its subclasses, each subclass has its own private
copy of the member.
My first reaction to this was that it was an unnecessary duplication. On thinking about it some more, I feel that the duplication might be justified as it reduces the amount of coupling between the base and derived classes and prevents a change in the base class causing inadvertent breakage in its subclasses.
Are protected
members "considered harmful" in C#?
I would consider protected fields harmful - and I would also consider the data duplication harmful, if the values should always be the same. However, the base class could expose the private field's value via a property instead:
class Base
{
private readonly MemberClass memberVariable;
protected MemberClass MemberProperty { get { return memberVariable; } }
public Base(MemberClass memberValue)
{
this.memberVariable = memberValue;
}
// methods accessing memberVariable or MemberProperty...
}
class Derived : Base
{
public Derived(MemberClass memberValue) : base(memberValue)
{
}
// methods accessing MemberProperty...
}
In C# 6, the base class becomes simpler:
class Base
{
protected MemberClass MemberProperty { get; }
public Base(MemberClass memberValue)
{
this.MemberProperty = memberValue;
}
// methods accessing MemberProperty...
}
That's still a protected property backed by a private readonly field - it's just the compiler does all the boilerplate for you.
See more on this question at Stackoverflow