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.
Related
I am much confused about static variable actually i am executing below program.
class ABC
{
public static int prop { get; set; }
const int i =5;
static int j;
public ABC()
{
prop = 8;
j = 9;
Console.WriteLine("Under ABC class's constructor.");
}
public int getValue()
{
j = 6;
prop = 89;
return j;
}
}
class Program
{
static void Main(string[] args)
{
ABC obj = new ABC();
Console.WriteLine(obj.getValue());
//Console.WriteLine(ABC.j);
Console.ReadLine();
}
}
And its executing without any compile or run time error.
I have following confusions.
can we assign static variable/property inside the non static constructor?
can we assign static variable/property inside the instance method also?
If we can do assignment in above two cases for static variable/property then what is the use of static constructor?
Finally what are the locations inside a class where we can assign/initialize a static variable/property?
can we assign static variable/property inside the non static
constructor?
Yes.
can we assign static variable/property inside the instance method
also?
Yes.
If we can do assignment in above two cases for static
variable/property then what is the use of static constructor?
A static constructor is also called a type initializer. It is responsible for initializing the type it is defined in. You may use it to perform calculations that can be done upfront and are the same for all instances of that type. You'll therefore save some execution time when creating an instance because the calculation has already been done by the type initializer. Note that the type initializer runs before the type is used the first time. So you cannot deterministically tell when it actually runs. You can also not catch exceptions thrown by it because you don't actually invoke the type initializer yourself. You therefore need to be careful not to put error prone operations inside type initializers (f.e. do not do IO operations inside them).
Finally what are the locations inside a class where we can
assign/initialize a static variable/property?
From anywhere. Note that, even across threads, you can read and write to a static member from anywhere. This makes it very hard to find bugs that may occure due to a programm mutation a static somewhere in memory.
As a side note: Try to avoid having mutable static memory to keep your application simpler. If you really need to ... you should consider locking access to the static resource to prevent data races.
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.
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.
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.