Reputation: 7963
When we want to control instantiation of objects, we often make the constructor private or internal:
public class A {
private A(int aParam) { }
}
However, this is essentially the same as sealing the class 'A' because now no one can inherit from it.
So, we can make the constructor protected:
public class A {
protected A(int aParam) { }
}
public class B {
protected B(int aParam) : base(aParam) { }
}
However, this means that any code from B (or any class derived from it) can instantiate a new A.
I am looking for a way to control instantiation but without having to make classes sealed (effectively or otherwise).
Note: I know that classes can always be instantiated with reflection and other tricks anyway; I'm only interested in creating an explicit 'contract'. If someone wants to subvert my contract deliberately that's up to them.
Upvotes: 3
Views: 577
Reputation: 73442
Am not sure what you mean. If am not wrong then you're trying to prevent instantiation of Base Class
from Derived Class
Right?
That is the default behavior too. You cannot instantiate base class from derived class when your base class constructor is protected
.
class Program
{
A a = A.CreateInstance();//works
B b = B.CreateInstanceOfB();//works
A ab = B.CreateInstanceOfA();//wont work
}
public class A
{
protected A()
{
}
public static A CreateInstance()
{
return new A();
}
}
public class B : A
{
protected B()
: base()//
{
}
public static B CreateInstanceOfB()
{
return new B();
}
public static A CreateInstanceOfA()
{
return new A();//This wont compile CS1540: Cannot access protected member...
}
}
Protected constructor is intended to invoke through constructor chaining(using base keyword) only. You can't instantiate it without reflection.
Hope this helps.
Upvotes: 1
Reputation: 35891
If you want to be able to instantiate subclasses, but prohibit explicit instantiation of a base class, then you have two options:
Add a pure virtual method thus making the base class abstract.
Add a protected constructor, and overload the "new" operator to disallow explicit instantiation of the base class, even though it's not abstract.
Upvotes: 0
Reputation: 564383
I am looking for a way to control instantiation but without having to make classes sealed (effectively or otherwise).
This is really contradictory in your requirements.
If you want to allow subclasses to be created, you must allow the subclass to effectively create the parent, which means you need to have, at a minimum, one protected
constructor. Without this, there would be no way for the subclass to initialize the instance properly.
By exposing a constructor as protected, you allow subclasses to change the instantiation rules (they can always add a public constructor).
There are really only two options here:
Upvotes: 7