The following code:
static void Main(string[] args)
{
Console.WriteLine("0");
string h = Foo.X;
Console.WriteLine("2");
}
public static class Foo
{
public static string X = ((Func<string, string>)delegate(string g)
{
Console.WriteLine(g);
return (g);
})("_aaa");
static Foo()
{
Console.WriteLine("ctor");
}
}
Will print:
0
_aaa
ctor
2
I know about the beforefieldinit behavior (with/without static constructor etc.).
The thing which I don't understand is why the ctor (in the output) is after _aaa?
It doesn't make any sense, what if I want to initialize variables in the constructor?
Question
Why does the initialization of X is before the ctor?
The reason ctor is after the field initializers is because that's the way it is specified. From the C# specification (emphasis is mine):
10.5.5.1 Static field initialization The static field variable initializers of a class correspond to a sequence of assignments that
are executed in the textual order in which they appear in the class
declaration. If a static constructor (§10.12) exists in the class,
execution of the static field initializers occurs immediately prior to
executing that static constructor. Otherwise, the static field
initializers are executed at an implementation-dependent time prior to
the first use of a static field of that class
If you want to have total control of your initialization order, move it all inside the constructor.
Related
After looking at so many complicated questions related to this i want to ask the explanation for following code having static field initialization. one more thing i want to know is the requirement of static field initialization. In which scenarios it ll be helpful??
using System;
class Test
{
static void Main()
{
Console.WriteLine("{0} {1}", B.Y, A.X);
}
public static int F(string s)
{
Console.WriteLine(s);
return 1;
}
}
class A
{
static A()
{ }
public static int X = Test.F("Init A");
}
class B
{
static B()
{ }
public static int Y = Test.F("Init B");
}
Output:
Init B
Init A
1 1
When no static constructor is present then output may vary. I am not able to understand the rationale behind it.What difference static field initialization has brought to this fragment?. Can someone please help. I am a newb with c#.
When a type has a static constructor, the runtime is constrained to execute all type initialization immediately before the first use of any member of the type.
When it doesn't have a static constructor, the runtime has much more freedom - it has to execute the type initializer at some point before the first use of a static field or before an instance is constructed, but that's all. You can even observe static methods which don't touch static fields being executed without the type initializer executing.
In your case, both A and B have static constructors, and the order of access to the members is B first, then A, hence your output. Without those static constructors, you'd still be guaranteed to get "1 1" as the last line, and you'd still get both "Init A" and "Init B", but the ordering of them wouldn't be guaranteed.
This is just the way the language and runtime are specified - and usually it has no impact, as usually type initializers should just be setting up the type, with no other side effects. Type initializers should do as little as possible, ideally - if they fail for some reason, the type will never be usable; type initializers aren't retried.
For more details, see my beforefieldinit article and .NET 4.0 type initializer changes blog post.
Do both of these code blocks do the same thing?
class A {
public static int s;
A(){}
static A(){s = 100;}
}
and
class A {
public static int s=100;
A(){}
//static A(){s = 100;} do not use
}
Do they do the same thing? I think so.
No, they don't behave quite the same way. Without the static constructor, the timing of exactly when the type initializer executes is much looser - it can happen earlier or later than you'd expect.
When there's a static constructor, the type initializer executes when the type is first used in terms of any static member being accessed or any instance being created.
When there isn't a static constructor, the only guarantee is that the initializer will be executed at some point before the first access of a static field (and still exactly once). Depending on the JIT, that might mean it's executed very early (e.g. when you first execute a method which might use a member) or very late (after calling static members which don't use any fields, or after creating and using an instance).
In IL, the difference is that a type without a static constructor has the beforefieldinit flag; one with a static constructor doesn't.
The effect is the same, but the actual order of execution may be different. When there is a static constructor, static fields are initialized immediately before the constructor is called or any of the static fields are accessed. If there is no static constructor, then the field initializers can be executed at any time prior to the first usage of one of the static fields.
Since your initializers have no side-effects and cannot throw exceptions, there would not be any discernable difference in the two, barring the use of reflection or some other outside observer (e.g. debugger)
Except for some edge cases such as beforefieldinit behavior, yes, they do the same thing. In fact, the compiled IL is nearly the same in the two cases. The only difference is the presence of beforefieldinit on the one without a static constructor.
class A
{
public static int s;
A() { }
static A() { s = 100; }
}
class B
{
public static int s = 100;
B() { }
}
Compiles to...
.class private auto ansi A
extends [mscorlib]System.Object
.class private auto ansi beforefieldinit B
extends [mscorlib]System.Object
With identical method/field definitions.
According to C# in a Nutshell the static constructor is executed when you first use of the property, and the most usage of this is when you want to calculate or read some data and set to the static property (Like a password from appconfig.config). without using the static constructor you must define a Init method and call it when your application has been started.
Something is not clear to me, according to what I read:
Field Initializers run before Constructors.
Static field Initializers execute before the static constructor is called (which is still compatible with point 1.).
If a type has no static constructor, field Initializers will execute before the type being used (as I understand : not being instantiated but rather being used)
This example explains :
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Foo.X);
Console.ReadLine();
}
}
class Foo
{
public static Foo Instance = new Foo();
public static int X = 3;
Foo()
{
Console.WriteLine("In constructor: " + X);
}
}
This Code Prints 0, then 3 ! How could that be possible? When we use Foo by doing Foo.X the two first initializers are called, before the constructor (that's ok so far), when
public static Foo Instance = new Foo();
is executed it should run its own 2 initializers before calling the constructor (Point 1) whereas it runs the constructor first and prints X with 0 as a default value.
I can't really follow the logic on this, please clarify to me.
Edit : what I expect to happen :
when Foo.X : execute: public static Foo Instance = new Foo();
before calling the constructor that prints ("In constructor: " + X), public static int X = 3; should be executed, but it happens that the constructor fires first, isn't supposed that the fields complete running first ? I mean even when jumping inside creating a new Foo instance fields must be run first.
From the two last points I expect to print 3 then 3
If a type has no static constructor, field Initializers will execute before the type being used (as I understand : not being instantiated but rather being used)
Not necessarily.
If there is no static constructor, then static field initializers will be executed at some time before a static field is first used - but the static field initializers don't have to execute before any instances are created.
From the C# 5 specification section 10.5.5.1:
The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration. If a static constructor (§10.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.
But in your case, you're just seeing that when the constructor of Foo is called in order to initialize Instance, X is still 0, because it hasn't been assigned a value. The field initializers are executed in textual order, so Instance is assigned a value before X. It's as simple as that - it's not a matter of timing between static fields and instance fields, as you haven't got any instance fields.
EDIT: It seems that you're being getting confused by the constructor call. Foo is already being initialized - the constructor call doesn't change that, and there's no "second initialization". The constructor is called normally, prints "0" and then returns. Then X is assigned a value of 3.
Foo() constructor is not a static constructor, hence its not run first as in with your case 3.
Hence, the fields are first initialized from top to bottom.
When static Foo is first initialized, it is executed and that is what prints 0, then when X is initialized, that's what is printed with System.Console.WriteLine() call.
The ones I am particularly concerned about are:
static variables in classes that are defined in referenced/dependency classes, contained in external DLLs. In my example, none of the types in that third party assembly is reference until later in the program. (let's say 5 min into execution).
Will the static variables of that third-party assembly only be loaded then?
Thanks,
rui
according to C# spec which says:
If a static constructor exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class. The example
whiteout a static constructor you can not predict exactly when a static variable is initialized but they are guaranteed to be initialized before their first use. but for sure they are not initialized before you reference their assemblies
All static fields are initialized before they are first used. This can be done by a type initializer (static constructor) explicitly declared or implicitly provided by the compiler. Static fields that do not have a value assigned in the class declaration will be initialized to the default value of their corresponding type.
Be careful if your static fields are object references whose constructors may throw exceptions:
class Foo
{
public Foo() { throw new Exception("boom"); }
}
class Bar
{
private static Foo baz = new Foo();
public Bar()
{
//trying to create a Bar will throw TypeInitializationException
}
public static void BarNone()
{
//trying to call a static method on Bar will throw TypeInitializationException
}
}
You'll get a TypeInitializationException when Bar is first used (either constructed or when a static method on Bar is called), as shown above.
I'm trying to understand when exactly static fields come into existence and have been reading this MSDN article - http://msdn.microsoft.com/en-us/library/79b3xss3 - but it seems to contradict itself:
First it says:
Static members are initialized before the static member is accessed for the first time and before the static constructor, if there is one, is called.
But then it goes on to say:
If your class contains static fields, provide a static constructor that initializes them when the class is loaded.
So, my question is basically this: When are static fields actually initialized and when do they first come into existence? Is it before the static constructor is called, during, or after?
Many thanks!
The C# Language specification states (in 10.5.5.1 Static field initialization):
The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration. If a static constructor (§10.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class
I believe the guidance in your second line is actually to initialize static fields that are not done inline, using field initializers. In that case, you should use a static constructor to guarantee that they will be initialized prior to usage.
As you can see from the specification, the actual "time" they come into existence is implementation specific, and subject to change. The only guarantee is that they will exist prior to the static constructor being called, which will always occur prior to their usage in code. This specification states (in 10.12):
The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
· An instance of the class type is created.
· Any of the static members of the class type are referenced.
It's like "normal" fields. So before the static constructor. You can check with a very simple program.
The order is:
static fields
static constructor
"normal" fields
"normal" constructor
A sample program:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Start");
int b = A.B;
Console.WriteLine("Read A.B");
new A();
Console.WriteLine("Built A");
}
}
class A
{
public static int B = mystaticfunc();
static int mystaticfunc() {
Console.WriteLine("Static field");
return 1;
}
static A()
{
Console.WriteLine("Static constructor");
}
int C = myfunc();
static int myfunc()
{
Console.WriteLine("Field");
return 1;
}
public A()
{
Console.WriteLine("Constructor");
}
}
Output:
Start
Static field
Static constructor
Read A.B
Field
Constructor
Built A
Static fields are guaranteed to be initialized prior to the first use of the class.
Optionally, you can provide a static constructor to control static initialization at the time it occurs.
The CLR doesn't have separate concepts of static member initialization and static constructor. Instead, there's just a single type initializer.
The C# compiler writes this type initializer for you, first it does initialization of static members, then it includes your code from any static constructor you defined.