2010-03-30 Jb Evain <jbevain@novell.com>
[mcs.git] / docs / ecma334 / 17.10.3.xml
blob13b86d5f97783ae8973ffd2462abc79760e5750d
1 <?xml version="1.0"?>
2 <clause number="17.10.3" title="Constructor execution">
3   <paragraph>Variable initializers are transformed into assignment statements, and these assignment statements are executed before the invocation of the base class instance constructor. This ordering ensures that all instance fields are initialized by their variable initializers before any statements that have access to that instance are executed. <example>[Example: For example: <code_example><![CDATA[
4 using System;  
5 class A  
6 {  
7    public A() {  
8       PrintFields();  
9    }  
10    public virtual void PrintFields() {}  
11 }  
12 class B: A  
13 {  
14    int x = 1;  
15    int y;  
16    public B() {  
17       y = -1;  
18    }  
19    public override void PrintFields() {  
20       Console.WriteLine("x = {0}, y = {1}", x, y);  
21    }  
22 }  
23 ]]></code_example></example></paragraph>
24   <paragraph>
25     <example>When new B() is used to create an instance of B, the following output is produced: <code_example><![CDATA[
26 x = 1, y = 0  
27 ]]></code_example></example>
28   </paragraph>
29   <paragraph>
30     <example>The value of x is 1 because the variable initializer is executed before the base class instance constructor is invoked. However, the value of y is 0 (the default value of an <keyword>int</keyword>) because the assignment to y is not executed until after the base class constructor returns. </example>
31   </paragraph>
32   <paragraph>
33     <example>It is useful to think of instance variable initializers and constructor initializers as statements that are automatically inserted before the <non_terminal where="17.10">constructor-body</non_terminal>. The example <code_example><![CDATA[
34 using System;  
35 using System.Collections;  
36 class A  
37 {  
38    int x = 1, y = -1, count;  
39    public A() {  
40       count = 0;  
41    }  
42    public A(int n) {  
43       count = n;  
44    }  
45 }  
46 class B: A  
47 {  
48    double sqrt2 = Math.Sqrt(2.0);  
49    ArrayList items = new ArrayList(100);  
50    int max;  
51    public B(): this(100) {  
52       items.Add("default");  
53    }  
54    public B(int n): base(n - 1) {  
55       max = n;  
56    }  
57 }  
58 ]]></code_example>contains several variable initializers; it also contains constructor initializers of both forms (base and this). The example corresponds to the code shown below, where each comment indicates an automatically inserted statement (the syntax used for the automatically inserted constructor invocations isn't valid, but merely serves to illustrate the mechanism). <code_example><![CDATA[
59 using System.Collections;  
60 class A  
61 {  
62    int x, y, count;  
63    public A() {  
64       x = 1;         // Variable initializer  
65       y = -1;         // Variable initializer  
66       object();        // Invoke object() constructor  
67       count = 0;  
68    }  
69    public A(int n) {  
70       x = 1;         // Variable initializer  
71       y = -1;         // Variable initializer  
72       object();        // Invoke object() constructor  
73       count = n;  
74    }  
75 }  
76 class B: A  
77 {  
78    double sqrt2;  
79    ArrayList items;  
80    int max;  
81    public B(): this(100) {  
82       B(100);         // Invoke B(int) constructor  
83       items.Add("default");  
84    }  
85    public B(int n): base(n - 1) {  
86       sqrt2 = Math.Sqrt(2.0);   // Variable initializer  
87       items = new ArrayList(100);  // Variable initializer  
88       A(n - 1);        // Invoke A(int) constructor  
89       max = n;  
90    }  
91 }  
92 ]]></code_example>end example]</example>
93   </paragraph>
94 </clause>