Based on what I have read, a constructor can have two meanings:
In computer programming languages the term default constructor can
refer to a constructor that is automatically generated by the compiler
in the absence of any programmer-defined constructors (e.g. in Java)
and
In other languages (e.g. in C++) it is a constructor that can be
called without having to provide any arguments, irrespective of
whether the constructor is auto-generated or used-defined
So in the context of C#, what does a default constructor means, does it mean a constructor that is auto-generated and its only job is to initialize the members to some default values?
In C# the default constructor is an empty constructor (with no parameters) generated for you by the compiler when you don't define any constructors.
Default constructor in C# is, by definition, a constructor with such signature:
Class()
{
}
No parameters are provided here, so the compiler can call this method without any doubts. If your class is providing some other constructors, the default one woudn't be generated by a compiler and you have to add it manually:
Class() : this(null)
{
}
Class(object data)
{
}
In default constructor you can define your logic for a class which is respresenting it's state, such as a private fields or outer components. The other purpose of the default constructors can be found in Dependency Injection containers, there it used for a default instantiation of the object you are mapping.
The default constructor in C# is an auto-generated constructor in case you haven't provided any. In that case the compiler will add the default public constructor which accepts no arguments.
However, as soon as you'll define any constructor, the default constructor won't be available any more.
In C#, the default constructor and the parameterless constructor are effectively synonymous. ie:
public MyClass()
{
}
Note that like in C++, providing a parameterized constructor removes the "provided" default one. You can always add a default/parameterless definition though.
Default constructor is parameterless constructor.
See: 10.10.4 Default constructors
If a class contains no instance constructor declarations, a
default instance constructor is automatically provided.
A default constructor is parameterless and is provided when the class contains no instance constructor declarations.
Try MSDN
Related
I have a base class Character which has several classes deriving from it. The base class has various fields and methods.
All of my derived classes use the same base class constructor, but if I don't redefine the constructor in my derived classes I get the error:
Error: Class "child class" doesn't contain a constructor which takes this number of arguments
I don't want to redefine the constructor in every derived class because if the constructor changes, I have to change it in every single class which, forgive any misunderstanding, goes against the idea of only writing code once?
You can use the following syntax to call the base class constructor from the classes that derive from it:
public DerivedClass() : base() {
// Do additional work here otherwise you can leave it empty
}
This will call the base constructor first, then it will perform any additional statements, if any, in this derived constructor.
Note that if the base constructor takes arguments you can do this:
public DerivedClass(int parameter1, string parameter2)
: base(parameter1, parameter2) {
// DerivedClass parameter types have to match base class types
// Do additional work here otherwise you can leave it empty
}
You can find more information about constructors in the following page:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/using-constructors
In a derived class, if a base-class constructor is not called explicitly by using the base keyword, the default constructor, if there is one, is called implicitly.
You do have to redeclare constructors, because they're effectively not inherited. It makes sense if you think of constructors as being a bit like static methods in some respects.
In particular, you wouldn't want all constructors to be automatically inherited - after all, that would mean that every class would have a parameterless constructor, as object itself does.
If you just want to call the base class constructor though, you don't need to write any code in the body of the constructor - just pass the arguments up to the base class as per Waleed's post.
If your base class starts requiring more information, it's natural that you should have to change all derived classes - and indeed anything calling the constructors of those classes - because they have to provide the information. I know it can seem like a pain, but it's just a natural consequence of what constructors do.
I had the same problem, and I solved it by replacing my constructor with a factory method like this:
A is the parent class.
public static T getChild<T>(int number) where T:A, new()
{
T child = new T();
T._number = number;
return child;
}
You can create a Child class with
Child b = A.getChild<Child>(2);
A kind of alternative could be to rely on a Dependency Injection container to initialize your objects, that way the that reference to the base class (could be the call to the base constructor or another initializer method) would "externalized" to the DI container.
I don't know if it makes sense to your case or not
I just read http://blog.gurock.com/articles/creating-custom-exceptions-in-dotnet/
I don't know when it is written. It says:
"Since C# unfortunately doesn’t inherit constructors of base classes, this new type only has the standard constructor with no parameters and is therefore relatively useless."
This says the same in 2010: C#: inheriting constructors
Is this still true?
EDIT: Following on from answers, I'm sure there would be a way around the default parameterless constructor. Are there other reasons for lack of constructor inheritance?
Constructors have never been inheritable in the entire lifetime of the C# language. That hasn't changed in C# 5.0: at the end of section 1.6.7.1 of the C# 5.0 spec, it still says:
Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.
So it still holds true today, and I imagine it will remain so in the foreseeable future.
You have to explicitly call the constructor of the base class, unless the base class defines a default constructor. So yes they are not inherited.
Which sometimes lead to a bunch of boiler plate code where you do nothing than pass arguments from one constructor to another
public class NegativArgument : Exception {
public NegativeArgument() : this("The number given was less than zero"){}
public NegativeArgument(string message) : this(message,null){}
public NegativeArgument(string message, Exception inner) : base:(message,inner){}
}
but what if you had an Exception type that should always have the same message? how would you solve that if the constructors were inherited? The exception class has a constructor that accepts a message so creating a new Exception type would in that case get that constructor too, not inheriting constructors makes it easy
public class NegativArgument : Exception {
public NegativeArgument() : base("The number given was less than zero"){}
}
If the base class does not have a default constructor you will have a compile error if you do not explicitly call a base class constructor.
Constructors are not inherited in C#.
If they were, then every class would have a default parameterless constructor (because all classes derive from Object and Object has a default parameterless constructor).
Many classes should only be constructed with specific values; this would be impossible to ensure if every class had a default parameterless constructor.
You should call them explicitly the constructor of the base classes. They are not inheritable.
Didn't change anything about them.
Check out : Constructors (C# Programming Guide)
From the spec §1.6.7.1:
Unlike other members, instance constructors are not inherited, and a
class has no instance constructors other than those actually declared
in the class. If no instance constructor is supplied for a class, then
an empty one with no parameters is automatically provided.
http://msdn.microsoft.com/en-us/library/ms228593.aspx
This answer is based upon the section "Constructors are not inherited" near the bottom of this entry on Jon Skeet's blog.
Summary
There are many cases in which a derived class may require information beyond that contained in the base class. Jon gives the example of the FileInfo class which requires additional information to be well-defined. Namely, that of the file for which info is to be provided
Any suggested 'fix' for this would entail overriding things in a way that prevents constructing such derived objects using the inherited constructors. However, knowingly requiring derived classes to override their base classes in a way that makes them more restrictive goes against best practice. (see: this question for Jon's discussion of the Liskov Substitution principle and the importance of being able to use derived classes wherever their base can be used.)
Additionally, from just a maintenance perspective, forcing manual override of constructors would make it difficult to reason about future behavior should the base class constructors change, and would entail having to always check, and often modify, any derived classes when new constructors are added to the base. Even a few of these would be problematic; but in cases where there are dozens or more such classes (and derived classes of those classes, etc.), maintenance and QA will quickly become a nightmare.
A default constructor has no parameters. And nor does a constructor that you write with no parameters. So what is the ultimate difference in c#?
Added to this when you inherit a default constructor and a parameterless constructor are they exposed on the inheritting type exactly the same? Because my IOC container doesn't seem to think so. (Unity).
Cheers,
Pete
The "default" constructor is added by the C# compiler if your class does not contain an explicit instance constructor. It is a public, parameterless constructor. If you have created an explicit non-public, parameterless constructor, Unity will not be able to use it in the same way it would have used a public constructor (regardless of whether this was generated by the compiler, and regardless of whether it had parameters).
You can override the behaviour of the default constructor by creating a parameterless constructor. A common use of this is when you have a custom object as a member of your class and you need to initialize it with a default value when an instance of your class created.
A default constructor is a synonym for a parameterless constructor.
Adding to #Sachin Kainth and #Fredrik Leijon answers, in .NET (also in Java) constructors are not inherited.
You either explicitly call a base constructor or, by default, the base parameterless constructor is invoked.
If you don't add a constructor then a default constructor with no parameters is inserted for you. If you add a constructor (with or without parameters) no default constructor is generated
I'll let the code speak for itself:
public class ThisHasADefaultConstructor
{
}
public class ThisHasAParameterlessConstructor
{
public ThisHasAParameterlessConstructor()
{
}
}
Note that a default constructor is effectively a parameterless constructor that is automatically generated when you don't specify a constructor (with or without parameters).
Maybe you need the the parameterless constructor if you want to have more constructors. Let's say one without parameters and one with parameters.
if your class has only a constructor with parameters, you're are not allowed to use the parameterless constructor, unless you define one, in other words, no default parameterless constructor is provided if you define a custom constructor in your class.
MSDN states:
A constructor that takes no parameters is called a default constructor. Default constructors are invoked whenever an object is instantiated using the new operator and no arguments are provided to new.
So the default constructor does not have to be automatically generated. A hand-written, parameterless constructor is also the default constructor.
This actually makes sense when you look at derived classes:
class A
{
public A() { ... } // do something
public A(object o) { ... } // do something else
}
class B
{
public B() { ... }
}
Which A constructor is called while creating B? The default one.
Default constructor refers to a constructor without parameters, wheter created automatically or created by you.
A defualt constructor is created automatically if you don't declare any other instance constructor, with or without paramters. (declaring a static constructor won't avoid the defautl constructor to be automatically created).
The constructors of a hierarchy of classes are not inherited, but all the constructor on the inheriting chain are invoked when using the constructor of a derived class, starting from the root of the hierarchy. Unless you specify which constructor to invoke, the default constructor of each class is invoked.
public class Base
{
public Base()
{
}
}
public class Derived : Base
{
public Derived()
{
}
}
// invokes, the Base() construtor, and then the Derived() constructor
var d = new Derived();
You can also explicitly invoke a base class constructor, with or without parameters like so:
// Derived class explicitly invoking base class constructor.
public Derived() :base()
{
}
If you want, you can invoke a base class constructor with parameters like so:
public Derived(int j) :base(j)
or so
public Derived() :base(23)
In this last code sample, if you create a Derived object with the default constructor, the constructor invoked in the base class isn't the default one, but a constructor with an integer parameter, invoked with the parameter 23.
(of course, this constructor with parameter must exist in the Base class).
You can only invoke explicitly the constructor of the inmediate base class.
A default contructor is called implicitly by the comppiler, except if you have explicitly created a new one (with no parameters).
I have written some code that works great, but I don't understand why it works. I want to serialize a class, with let's say an integer. So here is the code of the class.
[Serializable]
public class TestClass
{
public int Variable;
}
Now I want to have the possibility to create an instance of this class and setting the Variable right away. So I create a constructor and also a private default constructor for the serializer.
[Serializable]
public class TestClass
{
public int Variable;
private TestClass() {}
public TestClass(int value)
{
Variable = value;
}
}
So in the code where I'm using this, default parameters become handy. So I applied that technique to the public constructor.
[Serializable]
public class TestClass
{
public int Variable;
private TestClass() {}
public TestClass(int value = 0)
{
Variable = value;
}
}
And this all works fine, but why? Do we don't have now two constructors with the same definition? Even if I make the default constructor public, everything works fine. Once I remove the default constructor, it fails on serialisation. My first guess is that the XmlSerialize of .NET doesn't check for constructors with default parameters. But why does the compiler still allows this code?
I'm just curious on this, but also hope to learn and better understand how things work internally. Googling doesn't bring up anything useful, maybe just because I couldn't think about the right search terms.
The XmlSerializer specifically requires the class that it serializes to have a parameterless constructor, and if you put a breakpoint in your private constructor you'll notice that it's hit on deserialization. A constructor with default arguments is not a parameterless constructor, it is a constructor that takes parameters that are inserted for you by the compiler.
Overload resolution on a parameterless constructor vs a constructor with only default arguments (or any method in the same situation) comes down to specificity. Among the myriad of other overload resolution rules, the C# 4.0 language specification (7.5.3.2 Better function member) states:
Otherwise if all parameters of MP have a corresponding argument
whereas default arguments need to be substituted for at least one
optional parameter in MQ then MP is better than MQ.
From this information, we can simplify and ask a question about the constructors you have. When you say new TestClass(), which one should it pick?
We have specified all of the arguments that we would like to pass to the call. In
this case, it's zero.
Is there a constructor with exactly zero arguments that is visible to the
caller?
If so, call it.
If not, call the next best thing. In this case, it's your constructor that has default arguments.
Note that the XmlSerializer does not follow these rules. It knows specifically what it wants and will complain if you do not provide it.
I have just seen following code but I do not understand the derivation of base class right in the constructor declaration. What is this and is this possible with ordinal methods?
public SplashAppContext(Form mainForm, Form splashForm) : base(splashForm)
{
this.mainForm = mainForm;
splashTimer.Tick += new EventHandler(SplashTimeUp);
splashTimer.Interval = 2000;
splashTimer.Enabled = true;
}
It's calling a base class constructor, passing the argument splashForm of the type Form to it.
You can call base class methods as well. If you for example have overridden a method which behaviour you want to modify slightly, you do your modifications and call the base class method with base.TheMethod(). This would look like this:
public override void FireMissiles()
{
PrimeMissiles();
base.FireMissiles();
}
The syntax for calling a base class constructor and a base class method differs as you can see.
The syntax you've listed means that this constructor calls the superclass's constructor with the parameter splashForm before continuing with the rest of the construction of this object. When no superclass constructor is listed, the no-arg constructor is assumed, i.e:
public SplashAppContext(Form mainForm, Form splashForm)
{ ... }
is equivalent to
public SplashAppContext(Form mainForm, Form splashForm) : base()
{ ... }
What is this...
This line is called a constructor initializer. It means "call the base class's constructor with the parameter splashForm, then start this constructor's body".
When no constructor initializer is explicitly specified for a constructor, it's assumed that you want base(), the parameterless constructor.
...is this possible with ordinary methods?
For regular methods, you can of course call base class methods (with base.SomeMethod(...)), but there's no "initializer" style available.
: base(splashForm)
Is calling the parent constructor and passing splashForm to it.
This is actually not really a case of inheritance, what this syntax specifies is that before SplashAppContext's constructor is called, its base constructor should be called with splashForm passed as a parameter.
That is the syntax for calling the constructor of the immediate parent class. This is the C# syntax, whereas VB.NET requires that you call MyBase.New(splashForm) as the first line of code in your constructor.
This is expressed this way because a parent object is guaranteed to be fully constructed and initialized by the time your child constructor code begins to execute. Because of this, both compilers (VB.NET and C#) specify that you may not execute any of your own code before the parent constructor is called (if you don't specify a parent constructor and a parameterless constructor exists, it will be called automatically).
This syntax is not possible (nor necessary) for other method calls, as it's possible to invoke the base implementation of any other function by calling base.FunctionName() in your code. Constructors are just special cases because they have to execute before any other code.