Why can't I create an abstract constructor on an abstract C# class?
Solution 1
You cannot have an abstract constructor because abstract means you must override it in any non-abstract child class and you cannot override a constructor.
If you think about it, this makes sense, since you always call the constructor of the child class (with the new operator) and never the base class.
Generally speaking, the only way in C# to enforce a specific constructor signature is by using the new() generic constraint, which enforces the existence of a parameterless constructor for the type parameter.
Solution 2
Change that constructor in class A to
protected A(int a, int b)
{
// Some initialisation code here
}
Then your subclasses will have to use it, as there is no default constructor.
They can, however, still change the actual signature of the constructor. There is no way of forcing a subclass to use a specific signature for its constructor as far as I know. I'm pretty sure constructors can't be abstract.
What exactly do you need this for? We might be able to suggest a work around for this.
Solution 3
Although you can't override constructors, and therefore can't define an abstract constructor, you can place an abstract factory method in your abstract base class. All the derived classes would need to override that.
public abstract class A
{
abstract A MakeAInstance(int a, int b);
}
public class B : A
{
// Must implement:
override A MakeAInstance(int a, int b) {
// Awesome way to create a B instance goes here
}
}
Solution 4
Multiple reasons:
1) Constructors are not inherited thus you cannot override them.
2) The constructor is a static member function since it dont need a specific instance to be called. Abstract implies "virtual" which means that the implementation can vary depending on how a specific instance is subclassed, which is the opposite of the intention of the meaning of the "static" keyword.
Solution 5
You cannot enforce constructor signature, as each derived class may (must!) define its own constructor(s), and they may take any parameters they like.
If you need to pass a given set of variables to an object of a derived class, define an abstract method which needs to be implemented by derived classes. If the classes do not implement the abstract method, you will get a compiler error.
Greg Samson
Updated on July 08, 2022Comments
-
Greg Samson almost 2 years
I am trying to run lint and tests separately with tox-travis, but I cannot seem to get the right combo.
Here are the two base files:
tox.ini
[tox] envlist = py27, py34, py35, py36, lint [travis] python = 3.6: py36 3.5: py35 3.4: py34 2.7: py27 [travis:env] LINT = yes: py36, lint [testenv:lint] .... [testenv] ... commands = pip install -U pip py.test --basetemp={envtmpdir}
travis.yml
language: python python: - 3.6, lint - 3.5 - 3.4 - 2.7 matrix: include: - python: 3.6 env: - LINT=yes install: pip install -U tox-travis script: tox
- When
python={3.6,3.5,3.4,2.7}
andLINT
is not set only tests are run. (correct). - When
python=3.6
andLINT=yes
it runs NEITHER lint or tests. (incorrect)
Setting
LINT = yes: lint
- When
python={3.6,3.5,3.4,2.7}
andLINT
is not set only tests are run. (correct). - When
python=3.6
andLINT=yes
it runs neither tests or lint. (incorrect)
Setting:
3.6: py36,lint
andyes: lint
runs lint whenever python=3.6 regardless of LINT value.
What am I doing wrong here?
- When
-
Thorsten about 15 yearsI think they can add other constructors (with a different signature), but they'll be forced to implement at least the signature as defined in the protected "constructor".
-
Anthony D about 15 yearsThis answer does not accomplish what I want.
-
DkAngelito over 12 yearsbut in this case you must first create an instance of class B to be able to call the method MakeAInstance and get a new one
-
John Saunders over 12 yearsYes, exactly, or one must be passed to your code that then calls
instance.MakeAInstance(1,2)
-
Tilak about 12 yearscalling overrides in constructor is not recommended.
-
Matthew about 12 yearsI disagree with your statement of a constructor is a static member, it does need an instance to be called (since you can access instance methods, fields, etc.). The
new
keyword instanciates the object, and then the constructor gets called, the constructor itself doesn't "construct" the object. -
CptRobby over 10 yearsActually the .aspx and .aspx.cs both define the same class. So the .aspx page is not "inheriting" the class in the .aspx.cs code, (despite the fact that it is referred to in the
<%Page%>
directive as "Inherits") but is actually defining a partial to that same class. -
Syroot about 10 yearsDoes C# 6 change this rule with the primary constructors?
-
Jeppe Stig Nielsen about 9 yearsThe constructor is an instance method (i.e. a non-static method), as seen from a CIL perspective. It might look like:
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ... }
So its name is.ctor
, it isinstance
notstatic
, and its return type isvoid
. (Its accessibility maybe be different frompublic
, and its parameter list may contain some args.) -
jeromej over 5 yearsCan you give an example with
new()
? Isn't that the dangerous keyword that hides inherited member or it's something else? -
Sinjai over 2 yearsYears later: jeromej is referring to the keyword
new
, which is used to hide (NOT override, though the goal and outcome are simiilar) a member of the base class which is not virtual or abstract. That is different than thenew()
constraint.