static field initialization explanation and its requirement - c#

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.

Related

Static variable inside class

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.

Do both of these constructors do the same thing?

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.

Is the static initialization order of this code implementation specific?

I have a design that relies heavily on static initialization. I've noticed that after a series of OS updates, my design appears to be failing on some older versions of the .NET Framework (v<3.5), and only under Release configuration.
I think I've been able to narrow the issue down to a block of code similar in design to this:
public abstract class Foo { public static object A; }
public class Bar : Foo {
public static object B = InitB();
private static object InitB(){ return A }; }
public static void Main()
{
Foo.A = new object();
Bar bar = new Bar();
Console.Write((bar.B==null).ToString());
}
On .NET 2.0, under Release build, on my system, it appears my code is printing true. Whereas on .NET 4.5, it's printing false. Is the behavior of the code above implementation specific?
Your code relies on Bar's static constructor being called after the assignment to Foo.A. The language spec does not guarantee this. It only guarantees it if you actually write a static constructor, not if the compiler implicitly generates one: in that case, it may be called earlier than you expect.
To make sure your code behaves the same way in all valid implementations of .NET Framework, add a static constructor. You don't need to re-factor your initialisers, they can remain where they are.
public class Bar : Foo {
static Bar() { } // <-- add this
public static object B = InitB();
private static object InitB() { return A };
}
Alternatively, re-work your code in such a way that it still works even if the static constructor is called early.
Is the behaviour of the above code implementation specific
For the example above, the docs would suggest that is the case
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.
For consistency across .NET versions, and to force initialization order, you should add a static constructor to both classes.

Field initializer accessing `this`: invalid in C#, valid in Java? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
First, an introduction:
This code:
class C
{
int i = 5;
byte[] s = new byte[i];
}
fails to compile with the following error:
A field initializer cannot reference the nonstatic field, method, or property `C.i'
Resharper says something similar: Cannot access non-static field i in static context.
This is inline with what the C# spec says -- that a field initializer can't access the instance currently being created (this) or, by extension, any of the instance fields:
A variable initializer for an instance field cannot reference the
instance being created. Thus, it is a compile-time error to reference
this in a variable initializer, as it is a compile-time error for a
variable initializer to reference any instance member through a
simple-name.
However, this works just fine in Java:
class C {
int i = 5;
byte s[] = new byte[i]; //no errors here
}
Still with me? Ok, here's the question. Err, questions.
In a hypothetical world where this would be valid in C#, I'm wondering: would it even be possible? If so, what would be the pros and cons that it would add to the table?
Also, since it's really supported by Java, do the same pros/cons hold for Java? Or is there a fundamental difference in the way type initializers work in the two languages?
In short, the ability to access the receiver before the constructor body runs is a feature of marginal benefits that makes it easier to write buggy programs. The C# language designers therefore disabled it entirely. If you need to use the receiver then put that logic in the constructor body.
as for why the feature is legal in Java, you'll have to ask a Java designer.
In C#, field initializers are merely convenience semantics for the developer. The compiler moves all field initializers into the body of the constructor ABOVE where the call is made to the base constructor. So fields are initialized going up the ancestor chain, and the class is initialized from the base down.
Static references are ok because they are initialized before anything else.
By no means is this an authoritative answer, but let me make an educated guess.
There is a fundamental difference, and I think the answers to the other questions are related to this difference.
It lies in order-of-type-initialization, especially in the context of inheritance.
So, how does instance initialization work?
In C#:
all instance field initializers run first, "up" the inheritance chain, from most derived to base class.
then the ctors run, "down" the chain, from base to derived.
The possibility of ctors calling each-other or (explicitely) calling ctors of base classes doesn't change the situation, so I'll leave it out.
What basically happens is, this runs for each chass in the chain, starting with the most derived:
Derived.initialize(){
derivedInstance.field1 = field1Initializer();
[...]
Base.Initialize();
Derived.Ctor();
}
A simple example shows this:
void Main()
{
new C();
}
class C: B {
public int c = GetInt("C.c");
public C(){
WriteLine("C.ctor");
}
}
class B {
public int b = GetInt("B.b");
public static int GetInt(string _var){
WriteLine(_var);
return 6;
}
public B(){
WriteLine("B.ctor");
}
public static void WriteLine(string s){
Console.WriteLine(s);
}
}
Output:
C.c
B.b
B.ctor
C.ctor
That means that if accessing fields in a field initializer was valid, I could do this disaster:
class C: B {
int c = b; //b is a field inherited from the base class, and NOT YET INITIALIZED!
[...]
}
In Java:
Long, interesting article about type initialization here. To summarize:
It's a bit more complicated, because besides the notion of instance field initializers, there's the notion of an (optional) instance initializer, but here's the gist of it:
Everything runs down the inheritance chain.
the instance initializer of the base class runs
the field initializers of the base class run
the ctor(s) of the base class run
repeat above steps for the next class down the inheritance chain.
repeat previous step until reaching the most derived class.
Here's the proof: (or run it yourself online)
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
new C();
}
}
class C extends B {
{
WriteLine("init C");
}
int c = GetInt("C.c");
public C(){
WriteLine("C.ctor");
}
}
class B {
{
WriteLine("init B");
}
int b = GetInt("B.b");
public static int GetInt(String _var){
WriteLine(_var);
return 6;
}
public B(){
WriteLine("B.ctor");
}
public static void WriteLine(String s){
System.out.println(s);
}
}
Output:
init B
B.b
B.ctor
init C
C.c
C.ctor
What this means is, by the time a field initializer runs, all inherited fields are already initialized (by initializer OR ctor in base class), so it's safe enough to allow this behaviour:
class C: B {
int c = b; //b is inherited from the base class, and it's already initialized!
[...]
}
In Java, like in C#, the field initializers are run in the order of declaration.
The Java compiler even goes through the effort of checking that the field initializers aren't called out-of-order* :
class C {
int a = b; //compiler error: illegal forward reference
int b = 5;
}
* As an aside, you can access fields out-of-order if the initializer calls an instance method to do so:
class C {
public int a = useB(); //after initializer completes, a == 0
int b = 5;
int useB(){
return b; //use b regardless if it was initialized or not.
}
}
It is because field initialisers are moved into the constructor by the compiler (unless static) and so you would need be explicit in your constructor like this:
class C
{
int i = 5;
byte[] s;
public C()
{
s = new byte[i];
}
}
This is a bit of a non-answer, but I like to think of anything in the body of a class as being sequence-independent. It's not supposed to be sequential code that needs to be evaluated in a particular manner--it's just default state for the class. If you use code like that, you're expecting i to be evaluated before s.
Anyways, you can just make i a const (as it should be), anyways.

When do static fields come into existence?

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.

Categories

Resources