If I have a static variable in a class:
public class MyClass {
private static MyObject = new MyObject();
public void MyMethod() {
// do some stuff
}
}
Can the variable be instantiated when it is declared, as in the above?
Your code is legal and works.
One thing to be aware of is that static constructors and initalizers don't run when your module is loaded, but only when needed.
MyObject will only be instantiated when you either create an instance of MyClass or access a static field of it.
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.
The static constructor for a closed class type executes at most once in a given application domain. 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.
So as I understand it:
If there is no static constructor the calling of a static method may trigger the initializers but isn't required to do so if the static method uses no static field.
If there is a static constructor it must run when a static member is referenced, so calling of a static method triggers first the static field initializers and then the the static constructor.
Yes. Two particular things to note:
The static variables will be initialized in the order they appear in the class.
They are guaranteed to be initialized before any static constructor is called.
Section 10.5.5.1 of the C# spec goes into more detail in you are interested.
If you are asking if this is legal C#, then yes it is. And it will do what you think it will.
Related
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.
When I have a static field in my class:
public static int Counter = 0;
With a static constructor:
static Class() {
Counter++;
}
When I create an object of this class and check Class.Counter it shows me 1 which is correct.
But when I create another object of the same class, Class.Counter remains 1.
Why is that?
Because the static constructor is executed only once.
From C# Specification:
The static constructor for a class executes at most once in a given application domain. 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 is created.
Any of the static members of the class are referenced.
That is because you are incrementing your counter in static constructor, and it will be executed just once.
static constructor C# - MSDN
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.
You can fix it by incrementing in instance constructor like:
class Class
{
public static int counter = 0;
public Class()
{
counter++;
}
}
For thread-safety use Interlocked.Increment(ref counter); instead of counter++
Selman22 has it correct, here is a little more detail:
From MSDN
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.
Static constructors have the following properties:
A static constructor does not take access modifiers or have parameters.
A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
A static constructor cannot be called directly.
The user has no control on when the static constructor is executed in
the program.
A typical use of static constructors is when the class is using a log
file and the constructor is used to write entries to this file.
Static constructors are also useful when creating wrapper classes for
unmanaged code, when the constructor can call the LoadLibrary method.
If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.
Reference url: http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx
I am reading a code in C# that uses two constructors. One is static and the other is public. What is the difference between these two constructors? And for what we have to use static constructors?
static and public are orthogonal concepts (i.e. they don’t have anything to do with each other).
public simply means that users of the class can call that constructor (as opposed to, say, private).
static means that the method (in this case the constructor) belongs not to an instance of a class but to the “class itself”. In particular, a static constructor is called once, automatically, when the class is used for the first time.
Furthermore, a static constructor cannot be made public or private since it cannot be called manually; it’s only called by the .NET runtime itself – so marking it as public wouldn’t be meaningful.
Static constructor runs just once, before your class is instantiated. It's used if you want something to happen just once. A nice example would be a Bus class (similar to something they explain in MSDN article):
public class Bus
{
public static int busNo = 0;
static Bus()
{
Console.WriteLine("Woey, it's a new day! Drivers are starting to work.");
}
public Bus()
{
busNo++;
Console.WriteLine("Bus #{0} goes from the depot.", busNo);
}
}
class Program
{
static void Main(string[] args)
{
Bus busOne = new Bus();
Bus busTwo = new Bus();
}
// Output:
// Woey, it's a new day! Drivers are starting to work.
// Bus #1 goes from the depot.
// Bus #2 goes from the depot.
}
Static Constructor... It is guaranteed to be called "once" througout the life of the application/app Domain. It can contain statements that you want to be executed only once.
Public Constructor... Since we can not add access modifiers to a static constructor, a public constructor means you are talking about an instance constructor. If an instance constructor is public then the outside world can create its instances.
Other options are Internal ( can be called from within the library), Private ( from within the class only).
Static constructor called only the first instance of the class created but the public constructor called every time that instance of the class is created.
Static Constructor
A constructor declared using a static modifier is a static constructor.
A static constructor is used to initialize static data or to perform a
particular action that needs to be performed only once in the life cycle of
class. A static constructor is the first block of code to execute in class.
Static constructor executes one and only one time in the life cycle of
class. It is called automatically. The static constructor does not take
any parameters. It has no access to specifiers. It is not called
directly.
Instance or Public Constructor
Instance constructor is used to initialize instance data. Instance
constructor is called every time when the object of the class is created. It
is called explicitly. Instance constructor takes parameters. It has
access specifiers.
My source: Static Constructor Vs Instance Constructor in C#
I have the following code. Is it not the exact code which I am using since it is internal to my place of work, but is a representation of the scenario which I am encountering.
public class Service : ServiceBase
{
private static readonly Service _instance = new Service();
private static readonly string a = #"D:\test.txt";
private Service () : base()
{
// the value stored in "a" is always blank.
Console.Writeline(a);
}
static void Main(string[] args)
{
Run(_instance);
}
}
This code is a windows service (there is service specific code in the base class). For some reason the value stored in "a" is always blank in the constructor. Is there something obvious which is doing this, or is it a quirk in the .NET platform?
Swap round the declarations of the _instance and a fields. In C#, static fields are initialized in the order in which they're declared. In other words, your Server constructor is running too early.
Or you could declare a as const, which removes it from the construction process.
The problem is that you're calling the constructor before the initializer for a is run, so you're seeing the default value for a. In fact, it's not blank (an empty string) - it's null. You can fix this by reordering:
public class Service : ServiceBase
{
// Initialize a first
private static readonly string a = #"D:\test.txt";
private static readonly Service _instance = new Service();
...
}
The static initializers are run in the textual order (which becomes somewhat undefined with partial classes). From section 10.5.5.1 of the C# 3.0 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 (§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'm not sure I use that would though... it's too easy to break.
Can you change it to const? That would be more robust:
private const string a = #"D:\test.txt";
That way it won't matter if someone changes the order again at a later date, thinking that reordering is a harmless operation. Presumably you were unaware of the importance of the order here, otherwise you wouldn't have asked this question - how willing are you to gamble that another programmer looking at the same code won't have the same issue? :)
Static fields are instantiated in the order they appear in the text file. So your Service is being constructed before the string is initialized. if you swap those two lines it should work.
Link: http://msdn.microsoft.com/en-us/library/aa645758%28VS.71%29.aspx
Oh, and the singleton pattern is often an anti-pattern. Try to avoid using it if possible.
When I have class containing a static constructor, is that constructor called when the assembly containing the class is first loaded or when the first reference to that class is hit?
When the class is accessed for the first time.
Static Constructors (C# Programming Guide)
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.
It's not quite as simple as you might expect despite straightforward documentation. Jon Skeet's article http://csharpindepth.com/Articles/General/Beforefieldinit.aspx goes into this question in details.
Summary:
Static constructor is guaranteed to be executed immediately before the first reference to a member of that class - either creation of instance or own static method/property of class.
Note that static initilaizers (if there is no static constructor) guaranteed to be executed any time before first reference to particular field.
The static constructor is called before you use anything in the class, but exactly when that happens is up to the implementation.
It's guaranteed to be called before the first static member is accessed and before the first instance is created. If the class is never used, the static constructor is not guaranteed to be called at all.
In case static method is called from parent class, static constructor will not be called, althogh it is explicitly specified. Here is an example b constructor is not called if b.methoda() is called.
static void Main(string[] args)
{
b.methoda();
}
class a
{
public static void methoda()
{
//using initialized method data
}
}
class b : a
{
static b()
{
//some initialization
}
}
There seems to be a gotcha with static constructors that is answered elsewhere but took a while to digest into a simple explanation. All the docs and explanations claim the static constructor/intializers are "guaranteed" to run before the first class is instantiated or the first static field is referenced. The gotcha comes in when you try to put a static singleton in the class that creates an instance of itself (chicken/egg). In this case the static constructor ends up being called after the instance constructor - and in my case the instance constructor contained code that relied on some static data.
Static constructor called after instance constructor?
Static constructor can run after the non-static constructor. Is this a compiler bug?
(the answer for me was to put the singleton in a separate class or manually initialize the static data in the instance constructor before it is required)