I am wondering why my static constructor is outputting default constructor Static Constructor, and not the other way around Static Constructor and Default constructor or just Default constructor. When I use a static constructor, it should execute the static constructor first. However, from the code below,
The First question: why is the default constructor is called before the static constructor?
class Program
{
static void Main(string[] args)
{
var test = Single.S;
}
class Single{
static readonly Single s = new Single();
public static Single S{
get { return s; }
}
private Single(){
Console.WriteLine("Default");
}
static Single(){
Console.WriteLine("staic");
}
}
}
The Second question: How come the Static Single constructor is being called as well?
Depending on Microsoft
A static constructor is used to initialize any static data, or to
perform a particular action that needs to be performed once only. It
is called automatically before the first instance is created or any
static members are referenced.
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;
}
}
In this case, the static constructor will be called before the default constructor
but in this line,
static readonly Single s = new Single();
you are using "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 exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor.
in this case, static field initialization will be completed before the constructor is called,
then the static constructor is run before your default constructor,
but when it runs, it's using new Single(), so passing through your non-static constructor path.
This causes to call the default constructor before the static constructor.
Finally, you can try this and you will see it will execute
the static constructor before the default constructor
private class Single
{
private static readonly Single s;
static Single()
{
Console.WriteLine("static");
s = new Single();
}
}
References
C# and beforefieldinit
When is a static constructor called in C#?
How does static field initialization work in C#?
Static constructor called after instance constructor?
Static constructor can run after the non-static constructor. Is this a compiler bug?
The first thing that happens here when loading the class is
static Single s = new Single();
C# executes static initializers like this in the order they are seen. I am not sure if this ordering point also applies to the static constructor but from your test it seems that the static initializer does occur before the static constructor.
In any case, in order to assign to static Single s, one must first construct new Single(), which means invoking the non-static constructor. I am not sure what you would get if you read from Single.s in the non-static constructor but I would expect either null or an exception.
Related
Do I need to mark public method as static if I want to initialize private variable only once or it is enough for making "singleton property" in the following code?
public IEqualityComparer<T> GetComparer<T>()
{
if (typeof (IUserShift).IsAssignableFrom(typeof (T)))
return UserShiftComparer.Value as IEqualityComparer<T>;
throw new ArgumentOutOfRangeException("There is no avaliable comparer for the type!", nameof(T));
}
private static readonly Lazy<UserShiftTrackingComparer> UserShiftComparer = new Lazy<UserShiftTrackingComparer>();
If you make your field static then only one copy will exist and in this case since you have it within Lazy, it will only be created when it is accessed. If it is never accessed, it will never be created.
Making your method static means it is not tied to an instance of the class but the class itself. All instance methods can access static methods and static fields and instance fields and instance methods. On the other hand, static methods can only access static fields and other static methods.
To answer your question, you DO NOT need to make the method static to initialize the UserShiftComparer only once.
I have a class as follows :
static class Configuration
{
private static AppSettingsSection _appSettingsLogsSection;
static Configuration()
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
_appSettingsLogsSection = config.GetSectionGroup("Logs").Sections["appSettings"] as AppSettingsSection;
}
public static int LogSendIntervalMinutes = Convert.ToInt32(_appSettingsLogsSection.Settings["LogSendIntervalMinutes"]);
}
Now, as per my understanding, the static constructor should be called before the first reference to any static member is made. But surprisingly, it is not behaving like that. When I reference LogSendIntervalMinutes from Main class, instead of triggering the static constructor, call goes straight to the static field resulting in a NullReferenceException.
Am I doing something wrong here and is my understanding correct?
Static fields are always initialized before static constructor is called. You should initialize LogSendIntervalMinutes in static constructor as well. I'd suggest you even make it a property:
static class Configuration
{
private static AppSettingsSection _appSettingsLogsSection;
public static int LogSendIntervalMinutes { get; private set; }
static Configuration()
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
_appSettingsLogsSection = config.GetSectionGroup("Logs").Sections["appSettings"] as AppSettingsSection;
LogSendIntervalMinutes = Convert.ToInt32(_appSettingsLogsSection.Settings["LogSendIntervalMinutes"]);
}
}
Quote from C# language specification (I added the emphasis):
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.
From MSDN:
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.
So try to move the initialization to before the static constructor, or include the association in the static constructor itself.
And even though, you are trying something impossible, since the static field uses a variable declared inside the static constructor.
Try this:
private static AppSettingsSection _appSettingsLogsSection;
public static int LogSendIntervalMinutes;
static Configuration()
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
_appSettingsLogsSection = config.GetSectionGroup("Logs").Sections["appSettings"] as AppSettingsSection;
LogSendIntervalMinutes = Convert.ToInt32(_appSettingsLogsSection.Settings["LogSendIntervalMinutes"]); }
}
Look at the compile code using ILSpy or Reflector you will find your answer.
Actually field initializers are automatically moved inside constructor before your actual code of constructor. (static moves to static one and instance to instance contructor).
Decompile code of your class using reflector:
and actual class structure look like this:
Also you can see the optimization done by compiler to integrate two separate lines in constructor to single line to initialize _appSettingsLogsSection.
Initializations of static fields are actually part of the type constructor and are executed before the custom type constructor is called. Thus, if LogSendIntervalMinutes was an instance field, there would be no problem, but as it is static, its initialization is executed before your static constructor. You just need to put the initialization of LogSendIntervalMinutes inside the your type constructor.
I know the concepts of static constructor.
A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.
I want to know why class contains single static constructor only? What is the real time scenario for static constructor ?
How it differs from private constructor? I googled lot of links, but I can't get good idea.
http://social.msdn.microsoft.com/Forums/en-US/a9f8dcca-32d1-4a2b-b3fe-7d8f34f3b3f1/c-programmingstatic-constructor
Private vs Static constructors in .Net
i want to know why class contains single static constructor only?
Because it's being called automatically and there is no way to pass any parameter to that constructor. That's why only one, parameterless static constructor is possible.
what is the real time scenario for static constructor ?
You should use it for any work that has to be done before class is used and that has to be done only once.
how it differs from private constructor?
Private constructor is being run when you want it to run. Static constructor is run by CLR before class is used for the first time and you can determine when it happens.
And real-code example of static constructor usage - it creates an Expression Tree and compiles it to be used later and safe Expression Tree compilation from executing every time TestFunction is called:
class Test<T> where T : struct, IConvertible
{
private static Func<int, T> _getInt;
static Test()
{
var param = Expression.Parameter(typeof(int), "x");
UnaryExpression body = Expression.Convert(param, typeof(T));
_getInt = Expression.Lambda<Func<int, T>>(body, param).Compile();
}
public static T TestFunction(T x)
{
int n = Convert.ToInt32(x);
T result = _getInt(n);
return result;
}
}
Code from Convert class, IConvertible interface and Generics performance comparison test
if you want to compare static constructor with instance constructor you can think about it in such way.
Instance constructor is used to instantiate a new instance of particular class (it's no matter if its public, private or protected).
Static constructor is used to "initialize" a whole type. That's why a static constructor is called automatically before the first instance is created or any static members are referenced. Semantically it is just type initialization piece of code not the constructor (or you can treat it as type constructor).
Private constructor are just instance constructors with private access visibility (so you can use it to instantiate new instances just inside the same class where it is declared).
I want to write unit test for below class.
If name is other than "MyEntity" then mgr should be blank.
Negative Unit test
Using Manager private accessor I want to change name to "Test" so that mgr should be null.
And then will verify the mgr value.
To achieve this, I want to explicitly call the static constructor
but when I call the static constructor using
Manager_Accessor.name = "Test"
typeof(Manager).TypeInitializer.Invoke(null, null);
name is always set to "MyEntity" how to set name to "Test" and invoke the static constructor.
public class Manager
{
private static string name= "MyEntity";
private static object mgr;
static Manager()
{
try
{
mgr = CreateMgr(name);
}
catch (Exception ex)
{
mgr=null;
}
}
}
As I found out today, the static constructor CAN be called directly:
from another Stackoverflow post
The other answers are excellent, but if you need to force a class
constructor to run without having a reference to the type (ie.
reflection), you can use:
Type type = ...;
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
I had to add this code to my application to work around a possible bug in the .net 4.0 CLR.
For anyone finding this thread and wondering... I just did the test. It appears System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor() will only run the static constructor if it has not already been run for another reason.
For example, if your code isn't positive whether or not previous code may have accessed the class and triggered the static constructor to run, it doesn't matter. That previous access will have triggered the static constructor to run, but then RunClassConstructor() will not run it also. RunClassConstructor() only runs the static constructor if it hasn't already been run.
Accessing the class after RunClassConstructor() also does not result in the static constructor being run a second time.
This is based on testing in a Win10 UWP app.
Just add public static void Initialize() { } method to your static class and call it when you want. This is very similar to call constructor, because static constructor will be called automatically.
If you have a static member in your class (there must be, otherwise static constructor wouldn't do too much) then no need to explicitly call the static constructor.
Simply access the class where you would like to call its static constructor.
E.g.:
public void MainMethod()
{
// Here you would like to call the static constructor
// The first access to the class forces the static constructor to be called.
object temp1 = MyStaticClass.AnyField;
// or
object temp2 = MyClass.AnyStaticField;
}
Dear all, the question like this one has been already asked, but among the answers there was no explanation of the problem which I see.
The problem: the C# Programming Guide says:
A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.
In particular, static constructor is called before any instance of a class is created. (This doesn't ensure that the static constructor finishes before creation of instance, but this is a different story.)
Let's consider the example code:
using System;
public class Test
{
static public Test test = new Test();
static Test()
{
Console.WriteLine("static Test()");
}
public Test()
{
Console.WriteLine("new Test()");
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("Main() started");
Console.WriteLine("Test.test = " + Test.test);
Console.WriteLine("Main() finished");
}
}
It outputs:
Main() started
new Test()
static Test()
Test.test = Test
Main() finished
So we can see that the instance constructor finishes (and thus an instance is created) before the static constructor starts. Doesn't this contradict the Guide? Maybe the initialization of static fields is considered to be an implicit part of static constructor?
Inline initializers for static fields run before the explicit static constructor.
The compiler transforms your class into something like this:
public class Test {
.cctor { //Class constructor
Test.test = new Test(); //Inline field initializer
Console.WriteLine("static Test()"); //Explicit static ctor
}
.ctor { ... } //Instance constructor
}
Note that this is independent of the declaration order.
To quote the spec:
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.