Initialization order of static readonly field [duplicate] - c#

This question already has answers here:
Order of static constructors/initializers in C#
(4 answers)
Closed 8 years ago.
I'm curious of the C# spec says anything about the order of initializing static field's in C# 5 (.net4). For instance:
public class Test
{
public static readonly string A = "hi";
public static readonly string B = "bye";
public static readonly string DEFAULT = A;
}
In testing (Mono 2.x) they seem to be initialized in the order they appear in code. eg. As is, DEFAULT will have the value "hi", but if I move the definition for DEFAULT above A and B, it will be assigned NULL because A hasn't been assigned yet.
Is there a guarantee that the variables are initialized in order? Or is it up to the compiler?
Thanks.

It is in the order that they appear in. See here.
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.
Also, when you have a static constructor:
If a static constructor (Section 10.11) 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.

Related

Order of Instantiation [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 3 years ago.
Improve this question
A question I'm having trouble finding the answer to: When my class is instantiated, in what order are it's members instantiated.
For example, can I set a member to the value of a member lower in the declaration order? (See code example.)
// Can I do the following:
class foo
{
int A = B;
int B = 12;
}
// And this, for class types:
class bar
{
foo X = Y;
foo Y = new foo();
}
The order of field instantiation does not matter in this case. What matters is that you cannot use non-static field, method or property in the field initializer. So, it doesn't matter if you do:
class Foo
{
int A = B;
int B = 12;
}
or the opposite order
class Foo
{
int B = 12;
int A = B;
}
Your code will not compile anyway. You will get A field initialize cannot reference the non-static field, method, or property 'Foo.B' error.
So, you shouldn't worry about the order because this situation can never occur.
You just can't do it.
You will get the following compilation error :
Error CS0236 A field initializer cannot reference the non-static field, method, or property 'Program.foo.A' Test C:\Users\sebas\source\repos\Test\Test\Program.cs 14 Active
I you extend the question to static field, they are executed from the first to the latest one.
It can easily be tested with the following code :
class foo
{
public static int A = foo.B;
public static int B = 3;
public static int C = foo.B;
}
static void Main(string[] args)
{
Console.WriteLine(foo.A);
Console.WriteLine(foo.B);
Console.WriteLine(foo.C);
Console.ReadLine();
}
The result will be :
0
3
3
Anyway. Even if it was working, I would suggest that you just use a constructor. You will gain in maintainability.
Despite the bad example, it's worth understanding how initialization actually works. The draft C# 6.0 Spec has this to say about it:
The default value initialization described in Field initialization occurs for all fields, including fields that have variable initializers. Thus, when a class is initialized, all static fields in that class are first initialized to their default values, and then the static field initializers are executed in textual order. Likewise, when an instance of a class is created, all instance fields in that instance are first initialized to their default values, and then the instance field initializers are executed in textual order.
Source: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#field-initialization

Clarifying Understanding of Fields

I'm currently learning C# in Unity through a series of video tutorials and just had fields introduced. Am I correct in saying that fields are just variables declared in the class level?
Yes, you can say this.
The main difference is that variables in methods (also called local variables) have a temporary value used during the method call. The next time you call the method the previous value of the variables are lost and you have to initialize them again. (I am not talking about advanced stuff like iterators and captured variables.)
On the other side, variables in classes and structs, i.e. fields, are living as long as the object lives. I.e., they keep their value between method calls.
Unlike local variables that are first undefined, fields are assigned a default value when an object is created from a class. Struct fields behave differently depending whether the struct is used as class field or variable. The struct fields have thee same definedness as the field or variable defining them.
As #elgonzo commented, there are two types of fields
Static fields. They are declared with the static modifier. Static fields exist exactly once for a specific class or struct, independently of the number of objects of this type.
Instance fields exist once per object (i.e. class or struct instance).
Private instance fields can only be accessed by instance methods and constructors of this class or struct, where as private static fields can be accessed by static and instance methods and constructors. (Methods include getters and setters of properties and indexers.)
Example. With this class...
public class A
{
private static int _staticCounter;
private int _instanceCounter;
public void Count()
{
_staticCounter++;
_instanceCounter++;
}
public void PrintCount()
{
Console.WriteLine($"Static = {_staticCounter}, Instance = {_instanceCounter}");
}
public static void PrintStatic()
{
Console.WriteLine($"Static = {_staticCounter}"); // Can only access static fields.
}
}
...this test...
A x = new A();
A y = new A();
x.Count();
x.Count();
y.Count();
y.Count();
y.Count();
x.PrintCount();
y.PrintCount();
A.PrintStatic();
Console.ReadKey();
...prints this to the console
Static = 5, Instance = 2
Static = 5, Instance = 3
Static = 5

Trying to understand static constructors

I am trying to understand need for static constructors. None of information I found answered following question I have. Why would you do this
class SimpleClass
{
// Static variable that must be initialized at run time.
static readonly long baseline;
// Static constructor is called at most one time, before any
// instance constructor is invoked or member is accessed.
static SimpleClass()
{
baseline = DateTime.Now.Ticks;
}
}
as opposed to this
class SimpleClass
{
// Static variable that must be initialized at run time.
static readonly long baseline = DateTime.Now.Ticks;
// Static constructor is called at most one time, before any
// instance constructor is invoked or member is accessed.
//static SimpleClass()
//{
//}
}
?
This is not dupe of other question, this is about static constructors which don't accept parameters.
The need is somehow obvious: You want to do more than some field initialization for your static members.
Logically if you have this class:
class SimpleClass
{
// Static variable that must be initialized at run time.
static readonly long baseline = DateTime.Now.Ticks;
}
You can re-write it to have the same effect:
class SimpleClass
{
// Static variable that must be initialized at run time.
static readonly long baseline;
static SimpleClass () {
baseline = DateTime.Now.Ticks;
}
}
But instead, you could do more in your static constructor such as inspecting (using reflection) some properties and emiting some fast accessors / getters to them, or just simple notify other systems that your type has been created, etc.
From Jeffrey Richter CLR via C# book:
When the C# compiler sees a class with static fields that use inline
initialization (the BeforeFieldInit class), the compiler emits the
class’s type definition table entry with the BeforeFieldInit metadata
flag. When the C# compiler sees a class with an explicit type
constructor (the Precise class), the compiler emits the class’s type
definition table entry without the BeforeFieldInit metadata flag. The
rationale behind this is as follows: initialization of static fields
needs to be done before the fields are accessed, whereas an explicit
type constructor can contain arbitrary code that can have observable
side effects; this code may need to run at a precise time.
Obviouselly there is something more than this happening behind the scenes, I would suggest you to read entire chapter from CLR via C#: "Type Constructors"
This is an example of a possible difference:
class SimpleClass
{
static readonly long A = DateTime.Now.Ticks;
static readonly long B = DateTime.Now.Ticks;
static SimpleClass()
{
}
}
A and B are not guaranteed to be the same value, though if you were to write it in the constructor, you could guarantee it:
class SimpleClass
{
static readonly long A;
static readonly long B;
static SimpleClass()
{
var ticks = DateTime.Now.Ticks;
A = ticks;
B = ticks;
}
}
In addition, order matters for instantiation of static members.
According to ECMA-334 regarding static field initialization:
The static field variable initializers of a class declaration
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 (§17.11) 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
So, we can write something like this:
class SimpleClass
{
public static readonly long A = IdentityHelper.GetNext();
public static readonly long B = IdentityHelper.GetNext();
static SimpleClass()
{
}
}
public static class IdentityHelper
{
public static int previousIdentity = 0;
public static int GetNext()
{
return ++previousIdentity;
}
}
Here, A is guaranteed to be assigned before B. In this example, A will be 1, and B will be 2. We can guarantee that A < B (assuming the identity does not overflow and there's no issues with threading). Now, if we re-order the fields:
public static readonly long B = IdentityHelper.GetNext();
public static readonly long A = IdentityHelper.GetNext();
The functionality changes. Thus, we've created a side-effect which is not immediately clear simply by re-ordering the fields definitions.
A more likely scenario is, we may want to do this:
class SimpleClass
{
public static readonly long A = IdentityHelper.GetExpensiveResult().A;
public static readonly long B = IdentityHelper.GetExpensiveResult().B;
static SimpleClass()
{
}
}
Here, we're unable to share GetExpensiveResult() between the fields.

C# struct non-static struct member cannot have initializer [duplicate]

This question already has answers here:
Why can't I initialize my fields in my structs?
(4 answers)
Closed 8 years ago.
What is the cause of the error on the screen?
public struct YetkiYapisiListesi
{
public bool STOKGUNCELLE =false ;
public bool STOKSIL=false;
public bool STOKLISTELE=false;
}
Non-static struct member cannot have initializer
C# does not allow structs to have initializers, the reason why has been debated before, see here: ( Why can't I initialize my fields in my structs? )
Simply remove the = false part from your field declarations.
Note that Boolean fields are false by default, making your assignment completely unnecessary.
If you absolutely need fields to have initialized to non-default values then you can still define an additional constructor that sets those values, however it cannot be the default (parameterless) constructor. One alternative option then, is to use a static factory method.
You can't initialize field on Struct.
You will get the same result even if you ommit initializing :
public bool STOKGUNCELLE;
public bool STOKSIL;
public bool STOKLISTELE;
public bool STOKHAREKET;
Because bool default value are false .

Why can't we define a constant variable as static? [duplicate]

This question already has answers here:
Using consts in static classes
(4 answers)
Closed 9 years ago.
public static const string Var1 = "abc";//compile time error
public static readonly string Var2 = "def";
Why can't we define a constant as static ?
Constants are already static so that would be redundant and are resolved at compile time.
For example:
const X = 5;
int a = X + X;
Basically ends up as:
int a = 5 + 5;
However, the compiler optimizer will figure things out and actually emit 10.
See here for more information - http://msdn.microsoft.com/en-us/library/ms173119(v=vs.80).aspx
A const field already is static.
Everywhere you use it, its literal value is embedded in the generated IL.
Adding the static keyword at the point of declaration would be redundant.
From Static Classes and Static Class Members (C# Programming Guide):
Although a field cannot be declared as static const, a const field is essentially static in its behavior. It belongs to the type, not to instances of the type. Therefore, const fields can be accessed by using the same ClassName.MemberName notation that is used for static fields. No object instance is required.

Categories

Resources