constructors are executed in the order from top to bottom I.E. base\'s first followed by derived one. This arangement is based on an important OOP assurance that an object (
In C#, a constructor runs the sequence:
Perform all field initializers Chain to base class constructor Execute user-supplied code for constructor
In vb.net, the sequence is:
Chain to base class constructor Perform all field initializers Execute user-supplied code for constructor
There's no Framework-based reason why C# does things in the order that it does, as evidenced by the fact that vb.net can and does do them in a different sequence. The design justification for the C# approach is that there should be no possibility of an object being exposed to the outside world before all field initializers (for derived- as well as base-class fields) have run; since a base-class constructor could expose an object to the outside world, enforcing that requirement means that field initializers must run before the base-class constructor.
Personally, I do not find that justification particularly convincing. There are many scenarios in which it will not be possible to set fields to useful values without having information which will not be available before the base constructor has run. Any code whose base constructor may expose partially-constructed instances needs to be prepared for that possibility. While there are times when it would be useful to specify that a field initializer should run "early", I think there are many more situations where it is helpful for them to be able to access the fledgeling object (in some measure because I believe that class fields whose values should be regarded as invariants during the lifetime of a class instance should when practical be set declaratively via initializers rather than imperatively within a constructor).
Incidentally, one feature I'd like to see in both vb.net and C# would be a means of declaring parameter-initialized fields and pseudo-fields. If a class has a parameter-initialized field of a certain name and type, every constructor for that class which does not chain to another of the same class must contain parameters with the appropriate names and types. The values of those fields would be set in the constructor before anything else is done, and would be accessible to other field initializers. Pseudo-fields would behave syntactically like fields, except that they would only be usable within field initializers, and would be implemented as local variables within constructors. Such a feature would make many types of structures more convenient. For example, if a type is supposed to hold one particular array instance throughout its lifetime, being able to say:
readonly param int Length; readonly ThingType[] myArray = new ThingType[Length];
would seem nicer than having to either construct the array in the class constructor (which couldn't happen until after the base constructor had run) or (for vb.net) having to pass the length to a base-class constructor which could then use it to set a field (which would then occupy space in the class even if its value--like Length
above--might be redundant).
Why are field initializers of a derived class executed before the base class field initializers?
Good question. I answered your question in these blog posts from 2008:
https://docs.microsoft.com/en-us/archive/blogs/ericlippert/why-do-initializers-run-in-the-opposite-order-as-constructors-part-one
https://docs.microsoft.com/en-us/archive/blogs/ericlippert/why-do-initializers-run-in-the-opposite-order-as-constructors-part-two
Field initialisers are executed in the constructor, and as the constructor in the base class is called first, all field initialisers are also executed before the derived constructor executes.
Example:
public class Base {
// field initialiser:
private string _firstName = "Arthur";
public string FirstName { get { return _firstName;}}
public string LastName { get; private set; }
// initialiser in base constructor:
public Base() {
LastName = "Dent";
}
}
public class Derived : Base {
public string FirstNameCopy { get; private set; }
public string LastNameCopy { get; private set; }
public Derived() {
// get values from base class:
FirstNameCopy = FirstName;
LastNameCopy = LastName;
}
}
Test:
Derived x = new Derived();
Console.WriteLine(x.FirstNameCopy);
Console.WriteLine(x.LastNameCopy);
Output:
Arthur
Dent
Field Initializers are not meant to be a replacement for constructors.
As per MSDN documentation all field initializers are executed before constructors. However a restriction on the Field Initializer is that they cannot refer to other instance fields. ( http://msdn.microsoft.com/en-us/library/ms173118(v=vs.80).aspx)
The restriction is due to the fact that there is no way to identify the right order and the dependencies to execute the Field Initializers at a compiler level.
You would have to write a default constructor to achieve what you want. You could possibly try with a static field, however; it is a bad practice and might not even suit your design.
Edit for clarifying question asked in comment:
As far as a derived class is concerned, the base class fields look the same whether they are initialized through the initializer or the constructor. This information cannot be supplied to the child classes as this would mean exposing the implementation of the base class (which is strictly private to the base class).
This implies that the derived class Initializer has no way to figure out if all the base class fields have been initialized before accessing them. Hence the behavior is not allowed.