Simplified situation
public class A {
protected A() { }
protected A Make() { return new A(); }
}
public class B : A {
A a = new A(); //inaccessible due to protection level
B b = new B();
private B()
{
A c = new A();//inaccessible due to protection level
a = new A(); //inaccessible due to protection level
a = Make();
}
}
Why it's impossible to create instance of A in class B using class A protected constructor?
In my mind protected constructor is like protected method so it should be possible to run it in subclass.
Why it's impossible to create instance of A in class B using class A protected constructor?
You can't call a protected constructor using the new
modifier because the purpose of a protected constructor is that it can only be called from a derived classes point of view, thus not visible from the "outside".
The compiler doesn't infer the call to new A()
is being done from an instance of B
. That is why the constructor syntax is available, to guarantee a convention of how to call base constructors.
You can call A
constructor when declaring a constructor for B
:
public B(string foo) : base(foo)
This is what actually is being done on your behalf for a default constructor. For example:
public class A {}
public class B : A
{
public B() {}
}
Will yield the following IL:
// Methods
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x205a
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void A::.ctor() <--- This.
IL_0006: ret
} // end of method B::.ctor
One hackish way (I would avoid doing that) is to create such an instance can be achieved with Activator.CreateInstance
overload which accepts a bool
flag indicating the constructor is non-public:
var b = (B)Activator.CreateInstance(typeof(B), nonPublic: true);
You can make constructor A
protected internal
:
public class A
{
protected internal A() { }
protected A Make() { return new A(); }
}
So the type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class in another assembly.
Have a look at this link for more details: Many Questions: Protected Constructors
.
protected
members are accessible in a derived class (subclass) only through an instance reference of the type of the derived class (or a further derived class).
Here is an example with methods instead of constructors:
class B
{
protected void M() { }
}
class C : B
{
void X()
{
M(); // OK, same as this.M()
}
void Y(C otherC)
{
otherC.M(); // OK
}
void Z(B otherB)
{
otherB.M(); // compile-time error CS1540
}
}
So in the above example, you can call M
on a C
inside C
, but you cannot call M
on a B
inside C
.
Your example with instance constructors is analogous. A new
object expression is like calling an instance member (the instance constructor) on a (new) object of the type written after new
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With