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.
Related
The following code throws a NRE exception trying to log the exception:
public static class FooClass
{
public static string Foo { get; } = CalculateFoo();
static CalculateFoo()
{
try
{
DoSomethingThatFails();
}
catch (Exception ex)
{
_log.Debug(ex); // ----> _log is null here <----
}
}
static readonly ILog _log = LogManager.GetLogger("FooClass");
}
The reason _log is null, is because the compiler first initialize Foo property, and then it initializes the _log member.
A working solution is moving the _log initialization to the class top. This way the compiler first initializes _log and then Foo. However, we want to avoid that: In our organization, we have some coding rules that force us to sort code by visibility, so we first place public stuff at the class top, then, internal stuff, and finally private stuff.
Is there any way to tell the compiler the initialization order? If there is no way to do that, what would be, in your opinion, the best practices to fix this issue?
EDIT
I also tried to add a static constructor, but in that case the properties need to be calculated in the static constructor, just after initializing the _log.
Instead of initialising things inline, you can initialise them in the static constructor, while considering their dependencies:
public static class FooClass
{
// static constructors don't have a visibility, so your company's rules don't really apply here.
// either way, you can put this anywhere in the class
static FooClass() {
_log = LogManager.GetLogger("FooClass");
Foo = CalculateFoo();
}
public static string Foo { get; }
static string CalculateFoo()
{
...
}
static readonly ILog _log;
}
I also tried to add a static constructor, but in that case the properties need to be calculated in the static constructor, just after initializing the _log.
You have to. There's three things at play here:
A static constructor is called when its containing class is nonstatic and it is instantiated, or when any static member is referenced.
Static members in C# are initialized in textual declaration order.
Inline initializers (static Foo = Bar()) run before the static constructor.
The combination hereof causes your issue. So do as #Sweeper says: initialize all static members in a static constructor in an order you control. You can then adhere to your company's coding guidelines. Unless a new one pops up and proves them to be contradictory.
All of this can be avoided by not doing "SomethingThatFails" in a property getter. Getters should be quick and side-effect free. If they aren't, their logic should probably be in a method.
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.
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.
In the following code segment, I reference FILE_LOCATION from outside this class, and after execution flows into this class to access that constant, for some reason instead of continuing back to the location where the constant call was made, execution continues to instantiate the singleton.
My question is two parts; why is this happening and how can I work around it? I tried to create two partial classes, one solely for the constant and another for everything else, but execution still continued to the other partial class to instantiate the singleton.
public sealed class Foo
{
public static readonly string FILE_LOCATION = #"path\to\file";
// (singleton code modeled after:
// http://csharpindepth.com/articles/general/singleton.aspx --fourth version)
private static readonly Foo foo = new Foo();
// Rest of class implementation...
}
The property is referenced from an instance of a form class on a button click:
public partial class MyForm : Form
{
public void button1_Click(object sender, EventArgs e)
{
string s = Foo.FILE_LOCATION;
// this location is only reached AFTER the singleton is instantiated.
}
}
To answer your questions in order,
This occurs because C# guarantees that all static variables get initialized before you can access any individual static variable. When you call a static variable, accessing FILE_LOCATION, then all the static variable initializers run (including foo). After that, the static constructor runs. Since there is no explicit static constructor, nothing is done here. Then your code runs. The reason this occurs is that sometimes the value of a static variable might be initialized depending on another static variable, so it's required to initialize them all at the same time.
To work around this, instead of using public static readonly string FILE_LOCATION you can declare it as public const string FILE_LOCATION. The value of a const is determined at compile-time and not at run-time, and so the static variable foo will not be initialized when you access the FILE_LOCATION. This can work if you can determine the value of the file location at compile-time; is that something you can do in your application?
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).