I have a class structure like this where an abstract class A holds an interface IB and a concrete class C in two variables. Which classes get assigned to that interface variable depends on the actual subclass A1, A2 that inherits the abstract class, and need that class C that gets instantiated in the parent class constructor. So what I came up first was this:
abstract class A
{
protected readonly IB _b;
protected readonly C _c;
protected A()
{
_c = new C();
}
}
class B1 : IB
{
public B1(C c) {}
}
class B2 : IB
{
public B2(C c) {}
}
class A1 : A
{
public A1() : base()
{
_b = new B1(_c);
}
}
class A2 : A
{
public A2() : base()
{
_b = new B2(_c);
}
}
The assignment _b = new B1(_c); doesn´t work because its protected. I also can´t pass the class Bx down to the base constructor, because I need that to be executed before I can instantiate Bx. How else can I achieve my desired outcome?
_b = ...
doesn't work because readonly fields can only be initialised in the constructor of the class that declares it, not in a subclass. It's not because _b
is protected. The documentation says:
In a field declaration, readonly indicates that assignment to the field can only occur as part of the declaration or in a constructor in the same class.
One way to work around this is to have the superclass take in a Func<C, B1>
, and initialise _b
there.
protected A(Func<C, IB> bCreator)
{
_c = new C();
_b = bCreator(_c);
}
then:
class A1 : A
{
public A1() : base(c => new B1(c))
{
}
}
class A2 : A
{
public A2() : base(c => new B2(c))
{
}
}