Consider the following class snippet with two static member variables:
public static class Foo
{
static string A = GetA(B);
static string B = "required for A";
...
Now, my understanding is that A and B will be initialized when they are accessed for the first time. However, when I executed a fully-realized version of the snippet above where A was accessed before B was initialized, it led to null being passed in to GetA() instead of "required for A". Why isn't the behaviour to start initializing A, then, when it's realized that B is required to initialize A, initialize B, then return to finish the initialization of A?
What are the general rules around this? Why does it behave this way? I've seen other questions that touch on this (When do static variables get initialized in C#?) but they don't answer this question exactly. What is the static variable initialization order in C#? talks primarily about how this works across classes, not within a single class (though Jon Skeet's addendum to his answer -- "By popular demand, here was my original answer when I thought the question was about the initialization order of static variables within a class:...." does answer this question, it's buried in a much longer answer).
In short, don't do this.
Standard ECMA-334 C# Language Specification
15.5.6.2 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 (§15.5.6.1). Within a
partial class, the meaning of "textual order" is specified by
§15.5.6.1. If a static constructor (§15.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
The fix is to :
Put them in the order and use Static Constructor,
or just Initialise them in a Static Constructor in turn giving you the ability to control the order of initialisation (given the above information).
Personally i suggest to Initialise them in a Static Constructor, it seems to make it more concrete and understandable, and less likely to be bumped in refactoring
Related
A couple of days ago I asked myself about the difference, if any, between initializing static fields via
the static constructor and doing so by using a static field initializer (inline initialization of a static field at the point of declaration).
After reading plenty of stackoverflow questions on the subject and the famous Jon Skeet's article on the beforefieldinit flag I've now a much better understanding of the difference between the two initialization strategies.
There is one point that I'm not sure about, mostly because I wasn't able to find any official documentation about it.
The static construcutor is guaranteed to be executed only once and I think this holds true even in multi threading scenarios (when different threads create instances of the class and / or use static members of the class. In any case, the static constructor runs once and only once).
Is this true even for the inline initialization of the static fields ? Is the inline initialization of a static field guaranteed to be executed once even in multi threaded scenarios ?
Another point I'm still missing is what are the practical consequences of this difference in the initialization of the static fields of a class. Put another way, I would like to understand when the correctness of a piece of code can be affected by the choice of initializing a static fied inline at the point of declaration (instead of using the static constructor).
Most of the time (this depends mostly on the type of code that I usually work on, namely web applications) I use static readonly fields in service classes to store things that are used by the service I'm writing to perform computations or taking decisions. I decide to put these things inside static fields because they need to be the same for all the possible instances of the class I'm writing, they are actually invariants that don't belong to a particular instance, but instead they belong to the algorithm itself.
This is an example:
public class SomeInterestingService
{
private static readonly int ConstantNumber = 13;
private static readonly string[] Names = new[] { "bob", "alice" };
private readonly INumberGenerator numberGenerator;
public SomeInterestingService(INumberGenerator numberGenerator)
{
this.numberGenerator = numberGenerator ?? throw new ArgumenNullException(nameof(numberGenerator));
}
public int ComputeMagicNumber()
{
int answer = this.numberGenerator.GetNumber();
foreach(var name in names)
{
answer += name.Length;
}
answer += ConstantNumber;
return answer;
}
}
In code like this, is there any practical difference in chosing static constructor initialization or inline initialization of the static fields ConstantNumber and Names, apart from the difference in performance (inline initialization is more performant due to runtime optimizations that are not possible when using the static constructor) ?
Can the correctness of the code above be affected by the coiche in any strange corner case ? (I think not)
Original question:
In code like this, is there any practical difference in chosing static
constructor initialization or inline initialization of the static
fields ConstantNumber and Names, apart from the difference in
performance (inline initialization is more performant due to runtime
optimizations that are not possible when using the static constructor)
?
The answer is no. Either those properties are set upon each construction of the class (instance properties) or set upon the first call to any of the members or methods to the class (static properties).
What #Henk Holterman is saying that because the array of names is a reference type you could theoretically change any of the values in the array. Like:
Names[0] = "Henk Holterman";
Even though the property is readonly. Meaning, you can't assign a new instance of array to that property. The values in the array are not readonly. And could be manipulated if public or by calling a method of that class.
As the title suggests, I am interested in when static classes are loaded into memory in .NET, C# in particular. I assume it is similar to this question in Java and this question regarding static methods, in that it is loaded the first time it is used. Additionally, once it is in memory does it stay there until the application terminates or does is get cleaned up when the garbage collector comes along to clean up the class that used it?
I realize the small amount of memory a static class uses is not terribly important in a world of computers that have 8+GB of RAM standard, but it is always interesting to know the internals.
Edit:
The answers led me want to add more to this question and to clarify with an example. If I understand correctly, in the example below Contraption.SomeString will be placed in memory first followed closely by Contraption.AnotherString with the first time through the loop.
public static class Contraption
{
public static string SomeString = "Some String";
public static string AnotherString = "Another String";
}
public class Processor
{
public void Process(List<SomeClass> items)
{
foreach(var item in items)
{
if(item.Name == Contraption.SomeString)
{
//do something
}
if(item.Name == Contraption.AnotherString)
{
//do something
}
}
}
}
Regarding static fields initialization, an important point is the usage of static constructor. The CLR has a class loader component, which loads a class (metadata information) and request for memory allocation from the memory manager as they are used in the program. Metadata loading is one time job, post it just request memory on need basis
As understood in the discussion, the static class variables are loaded on the first usage of the class anywhere, and are assigned the memory, but using the static constructor can ensure that they are initialized as the first thing when class loader is invoked, its a one time call, which can do the initialization of all the static variables in a class, this even precede the first usage policy, as its when CLR (mscoree.dll) is components are loaded for a given program.
Static constructor is never called after first time under any circumstance (except program restart), even if there's an exception, its quite widely used, also static variables can be collected by setting them as null
I assume you're referring to fields within static classes (or static fields in non-static classes). They will be initialized before the first use. It's described in the C# specification:
10.4.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 (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.
Static class members are considered Garbage Collection roots and all always reachable.
You can force the objects to be reclaimed by resetting the static member to null or other object:
public static class Foo
{
public static object Bar = new object();
}
// somewhere later
Foo.Bar = null;
// the object can be collected now.
Static variables persist for the lifetime of an AppDomain, and in .NET, you can have multiple AppDoamins per application. Although most of the time, it is just one AppDomain per application, and other AppDomains are mostly created for sandboxing plugins.
https://msdn.microsoft.com/en-us/library/2bh4z9hs(v=vs.110).aspx
Is there any way to force the static field initialization order in partial classes? Let's say in HelloWorld1.cs I have:
partial class HelloWorld
{
static readonly string[] a = new[] { "Hello World" };
}
Elsewhere in HelloWorld2.cs I have:
partial class HelloWorld
{
static readonly string b = a[0];
}
If a is initialized before b this is fine but if b is initialized before a then it throws an. The healthy way is probably to use a static constructor but I'm curious if there's a way to force or predict the initialization order when the fields classes are in different files of the same partial class.
When the fields are present in the same file, the textual order defines the execution of their initialization:
10.5.5.1 Variable initializers - 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.
However, in the case of fields declared in different files of partial classes, the order is undefined:
10.2.6 Partial types - Members
The ordering of members within a type is rarely significant to C# code, but may be significant when interfacing with other languages and environments. In these cases, the ordering of members within a type declared in multiple parts is undefined.
From the C# language specification.
From MSDN Documentation:
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
(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.
If I have a static class with a static field such as:
private static myField = new myObject();
I then have a bunch of static methods that use myField.
Is myField re-instantiated for each method call? My guess is that it's instantiated the first time a method is called that uses it and it remains in memory until the GC clears it up?
Cheers for any pointers :-)
No, it is assigned to one time, when the class is first accessed. The GC will not release the memory for this instance while the application is running - the memory will be freed when the AppDomain unloads.
There is an article by Jon Skeet about initializing and the beforefieldinit flag. It explains a bit about initializing and quotes the important parts of the C# spec, too.
It is instantitated only once. It is intantiated the moment you use a static method for the first time.
You can also instantiate it in the static construtor.
A static field initializer is run once for a given app domain, and the field remains available for the life of the program. The CG will not collect any object that is referenced by a static member variable.
If the class has a static constructor, then the static field initializer is executed just before that constructor, which occurs the first time a static member is referenced or an instance constructor is executed. If there is no static constructor, then the field is initialized at some undetermined time before any static members or instance constructors are executed.
It is assigned only once, during class initialization. That happens effectively the first time the class is "actively" touched. See: class initialization in JVM spec for exact details of when the class will be initialized.
Assuming the class this code is in is called MyClass, myField will be GCed shortly after the classloader that loaded MyClass is GCed. (classes get unloaded at classloader granularity in all the major JVMs).
What are the benefits of having a member variable declared as read only? Is it just protecting against someone changing its value during the lifecycle of the class or does using this keyword result in any speed or efficiency improvements?
I don't believe there are any performance gains from using a readonly field. It's simply a check to ensure that once the object is fully constructed, that field cannot be pointed to a new value.
However "readonly" is very different from other types of read-only semantics because it's enforced at runtime by the CLR. The readonly keyword compiles down to .initonly which is verifiable by the CLR.
The real advantage of this keyword is to generate immutable data structures. Immutable data structures by definition cannot be changed once constructed. This makes it very easy to reason about the behavior of a structure at runtime. For instance, there is no danger of passing an immutable structure to another random portion of code. They can't changed it ever so you can program reliably against that structure.
Robert Pickering has written a good blog post about the benefits of immutability. The post can be found here or at the archive.org backup.
The readonly keyword is used to declare a member variable a constant, but allows the value to be calculated at runtime. This differs from a constant declared with the const modifier, which must have its value set at compile time. Using readonly you can set the value of the field either in the declaration, or in the constructor of the object that the field is a member of.
Also use it if you don't want to have to recompile external DLLs that reference the constant (since it gets replaced at compile time).
There are no apparent performance benefits to using readonly, at least none that I've ever seen mentioned anywhere. It's just for doing exactly as you suggest, for preventing modification once it has been initialised.
So it's beneficial in that it helps you write more robust, more readable code. The real benefit of things like this come when you're working in a team or for maintenance. Declaring something as readonly is akin to putting a contract for that variable's usage in the code. Think of it as adding documentation in the same way as other keywords like internal or private, you're saying "this variable should not be modified after initialisation", and moreover you're enforcing it.
So if you create a class and mark some member variables readonly by design, then you prevent yourself or another team member making a mistake later on when they're expanding upon or modifying your class. In my opinion, that's a benefit worth having (at the small expense of extra language complexity as doofledorfer mentions in the comments).
To put it in very practical terms:
If you use a const in dll A and dll B references that const, the value of that const will be compiled into dll B. If you redeploy dll A with a new value for that const, dll B will still be using the original value.
If you use a readonly in dll A and dll B references that readonly, that readonly will always be looked up at runtime. This means if you redeploy dll A with a new value for that readonly, dll B will use that new value.
There is a potential case where the compiler can make a performance optimization based on the presence of the readonly keyword.
This only applies if the read-only field is also marked as static. In that case, the JIT compiler can assume that this static field will never change. The JIT compiler can take this into account when compiling the methods of the class.
A typical example: your class could have a static read-only IsDebugLoggingEnabled field that is initialized in the constructor (e.g. based on a configuration file). Once the actual methods are JIT-compiled, the compiler may omit whole parts of the code when debug logging is not enabled.
I have not checked if this optimization is actually implemented in the current version of the JIT compiler, so this is just speculation.
Keep in mind that readonly only applies to the value itself, so if you're using a reference type readonly only protects the reference from being change. The state of the instance is not protected by readonly.
Surprisingly, readonly can actually result in slower code, as Jon Skeet found when testing his Noda Time library. In this case, a test that ran in 20 seconds took only 4 seconds after removing readonly.
https://codeblog.jonskeet.uk/2014/07/16/micro-optimization-the-surprising-inefficiency-of-readonly-fields/
Don't forget there is a workaround to get the readonly fields set outside of any constructors using out params.
A little messy but:
private readonly int _someNumber;
private readonly string _someText;
public MyClass(int someNumber) : this(data, null)
{ }
public MyClass(int someNumber, string someText)
{
Initialise(out _someNumber, someNumber, out _someText, someText);
}
private void Initialise(out int _someNumber, int someNumber, out string _someText, string someText)
{
//some logic
}
Further discussion here: http://www.adamjamesnaylor.com/2013/01/23/Setting-Readonly-Fields-From-Chained-Constructors.aspx
Adding a basic aspect to answer this question:
Properties can be expressed as readonly by leaving out the set operator. So in most cases you will not need to add the readonly keyword to properties:
public int Foo { get; } // a readonly property
In contrast to that: Fields need the readonly keyword to achieve a similar effect:
public readonly int Foo; // a readonly field
So, one benefit of marking a field as readonly can be to achieve a similar write protection level as a property without set operator - without having to change the field to a property, if for any reason, that is desired.
Be careful with private readonly arrays. If these are exposed a client as an object (you might do this for COM interop as I did) the client can manipulate array values. Use the Clone() method when returning an array as an object.
Another interesting part of usage of readonly marking can be protecting field from initialization in singleton.
for example in code from csharpindepth:
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
readonly plays small role of protecting field Singleton from being initialized twice. Another detail is that for mentioned scenario you can't use const because const forces creation during compile time, but singleton makes creation at run time.
If you have a pre defined or pre calculated value that needs to remain same through out the program then you should use constant but if you have a value that needs to be provided at the runtime but once assigned should remain same throughout the program u should use readonly. for example if you have to assign the program start time or you have to store a user provided value at the object initialization and you have to restrict it from further changes you should use readonly.
readonly can be initialized at declaration or get its value from the constructor only. Unlike const it has to be initialized and declare at the same time.
readonly has everything const has, plus constructor initialization
code https://repl.it/HvRU/1
using System;
class MainClass {
public static void Main (string[] args) {
Console.WriteLine(new Test().c);
Console.WriteLine(new Test("Constructor").c);
Console.WriteLine(new Test().ChangeC()); //Error A readonly field
// `MainClass.Test.c' cannot be assigned to (except in a constructor or a
// variable initializer)
}
public class Test {
public readonly string c = "Hello World";
public Test() {
}
public Test(string val) {
c = val;
}
public string ChangeC() {
c = "Method";
return c ;
}
}
}
There can be a performance benefit in WPF, as it removes the need for expensive DependencyProperties. This can be especially useful with collections