What exactly are Static Constructor in C#? - c#

I have couple of question regarding Static Constructor in C#.
What exactly are Static Constructor and how they are different from non-static Constructor.
How can we use them in our application ?
**Edited
public class Test
{
// Static constructor:
static Test()
{
Console.WriteLine("Static constructor invoked.");
}
public static void TestMethod()
{
Console.WriteLine("TestMethod invoked.");
}
}
class Sample
{
static void Main()
{
Test.TestMethod();
}
}
Output :
Static constructor invoked.
TestMethod invoked.
So, this means that static constructor will be called once. if we again call Test.TestMethod(); static constructor won't invoke.
Any pointer or suggestion would be appreciated
'
Thanks

Static constructors are constructors that are executed only ONCE when the class is loaded. Regular (non-static) constructors are executed every time an object is created.
Take a look at this example:
public class A
{
public static int aStaticVal;
public int aVal;
static A() {
aStaticVal = 50;
}
public A() {
aVal = aStaticVal++;
}
}
And consider this code:
A a1 = new A();
A a2 = new A();
A a3 = new A();
Here, static constructor will be called first and only once during the execution of the program. While regular constructor will be called three times (once for each object instantiation).
static constructors are usually used to do initialization of static fields for example, assigning an initial value to static fields.. Do keep in mind that you will only be able to access static members (methods, properties and fields) on static constructors.
If you need to "execute the static constructor multiple times", you can't do that. Instead, you can put the code you want to run "multiple times" in a static method and call it whenever you need. Something like:
public class A {
public static int a, b;
static A() {
A.ResetStaticVariables();
}
public static void ResetStaticVariables() {
a = b = 0;
}
}

You use them the same way you use instance constructors - to set default values. Only in this case you'll be initializing static fields, so static constructors get executed only once.
Be aware that the code in static constructor won't be executed until the first call to the class was made.

it runs when class is loaded.
It will print :
{
hi from static A
A
}
public class A{
static A{
print("hi from static A");
}
public A() {
print("A");
}
main() {
new A();
}
}

Related

Is a static collection guaranteed to be initialized/populated before another class uses it?

Suppose I have these 2 classes:
public class A<T> where T : IEntityWithID, new()
{
private static EntityInfo entityInfo = B.GetEntityInfo(typeof(T));
private static IEnumerable TestCases
{
// Do work with entityInfo...
}
}
private static class B
{
private static IList<EntityInfo> entityInfoList = B.GetEntityList();
public static EntityInfo GetEntityInfo(Type type)
{
return entityInfoList.Single(e => e.Types.Contains(type));
}
private static IList<EntityInfo> GetEntityList()
{
// Builds a list of EntityInfo's...
}
}
Is the entityInfoList in class B guaranteed to be initialized and populated before B.GetEntityInfo() is called in class A?
Yes, it is guaranteed. Here's a snippet from MSDN:
The program cannot specify exactly when the class is loaded. However,
it is guaranteed to be loaded and to have its fields initialized and
its static constructor called before the class is referenced for the
first time in your program.
EDIT: As pointed out, you could end up in a situation where 2 static classes depend on each other for initialization which could get you in trouble, but as long as that's not the case, you're fine.
No, if you have circular dependencies it's possible to run code from a class before that class's static initialization has finished.
Here's a simple example of a static field initialized to 5, and yet an external class observes that field being null:
public class A
{
public static void Foo()
{
Console.WriteLine(B.bar == null);
}
}
public class B
{
public static readonly object bar = Foo();
public static object Foo()
{
A.Foo();
return 5;
}
}
private static void Main(string[] args)
{
var bar = B.bar;
}
This will print true.

Why can't I call 'public void' from the same class?

My understanding of the method structures is limited to a very limited spectrum of structures:
public / private
static
void / variable returns
string, int etc.
So why can't I call a method within the same class?
class ClassName
{
public void Method1()
{
// do stuff...
}
public static void Method2()
{
// This won't work?
Method1();
// do stuff...
}
}
You can't call a non-static method from a static method.
If you really want to do that from withing a static method, you need to instantiate the class, something like:
class myClass
{
public void Method1(){
//Stuffs
}
public static void Method2(){
myClass c=new myClass();
c.Method1();
}
}
You can't call a method that isn't static from a static method..
Static = belongs to the class
Otherwise it belongs the instance of the class.
See MSDN reference for more information about static methods.
You can't call a non static element from a static context. You would have to create an instance of your class in your static method and call the non static method from that instance. A static method can be called without an instance.

Generic static fields initialization

I'm just getting curious about the following code :
public static class Container<T>
{
public static readonly T[] EmptyArray = new T[0];
}
As I've understood the static class Container will be initialized when the following code executes:
...
var emptyArray = Container<int>.EmptyArray;
...
Am I right ? Any explanations on static generic classes/members initialization would be appreciated. Thanks in advance.
The guarantee is that the static field is initialized before you access it. (And also, if there is also a static constructor, then all static fields will be initialized before the static constructor is run.)
For generic classes, static initialization works on a per-type basis, so Container<int> acts as if it is a completely different class to Container<double>. This is actually true for all static parts of a generic class - each type gets its own 'copy'.
An example will show this last point more clearly:
static class Foo<T>
{
static int count = 0;
public static int Increment()
{
return ++count;
}
}
public class Program
{
public static void Main()
{
Console.WriteLine(Foo<int>.Increment());
Console.WriteLine(Foo<int>.Increment());
Console.WriteLine(Foo<double>.Increment());
}
}
Output:
1
2
1
Static field initializers are really moved into the static constructor (type initializer) of the class. So your code compiles into this automagically:
public static class Container<T>
{
public static readonly T[] EmptyArray;
static Container()
{
EmptyArray = new T[];
}
}
From MSDN about static constructors:
It [Static Constructor] is called automatically before the first instance is created or any static members are referenced.
Since Container<string> and Container<bool> are not the same, the static constructor is called once for each type of T.

What's the best way to ensure a base class's static constructor is called?

The documentation on static constructors in C# 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.
That last part (about when it is automatically called) threw me for a loop; until reading that part I thought that by simply accessing a class in any way, I could be sure that its base class's static constructor had been called. Testing and examining the documentation have revealed that this is not the case; it seems that the static constructor for a base class is not guaranteed to run until a member of that base class specifically is accessed.
Now, I guess in most cases when you're dealing with a derived class, you would construct an instance and this would constitute an instance of the base class being created, thus the static constructor would be called. But if I'm only dealing with static members of the derived class, what then?
To make this a bit more concrete, I thought that the code below would work:
abstract class TypeBase
{
static TypeBase()
{
Type<int>.Name = "int";
Type<long>.Name = "long";
Type<double>.Name = "double";
}
}
class Type<T> : TypeBase
{
public static string Name { get; internal set; }
}
class Program
{
Console.WriteLine(Type<int>.Name);
}
I assumed that accessing the Type<T> class would automatically invoke the static constructor for TypeBase; but this appears not to be the case. Type<int>.Name is null, and the code above outputs the empty string.
Aside from creating some dummy member (like a static Initialize() method that does nothing), is there a better way to ensure that a base type's static constructor will be called before any of its derived types is used?
If not, then... dummy member it is!
You may call static constructor explicity, so you will not have to create any methods for initialization:
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof (TypeBase).TypeHandle);
You may call it in static constructor of derived class.
As others have noted, your analysis is correct. The spec is implemented quite literally here; since no member of the base class has been invoked and no instance has been created, the static constructor of the base class is not called. I can see how that might be surprising, but it is a strict and correct implementation of the spec.
I don't have any advice for you other than "if it hurts when you do that, don't do that." I just wanted to point out that the opposite case can also bite you:
class Program
{
static void Main(string[] args)
{
D.M();
}
}
class B
{
static B() { Console.WriteLine("B"); }
public static void M() {}
}
class D: B
{
static D() { Console.WriteLine("D"); }
}
This prints "B" despite the fact that "a member of D" has been invoked. M is a member of D solely by inheritance; the CLR has no way of distinguishing whether B.M was invoked "through D" or "through B".
The rules here are very complex, and between CLR 2.0 and CLR 4.0 they actually changed in subtle and interesting ways, that IMO make most "clever" approaches brittle between CLR versions. An Initialize() method also might not do the job in CLR 4.0 if it doesn't touch the fields.
I would look for an alternative design, or perhaps use regular lazy initialization in your type (i.e. check a bit or a reference (against null) to see if it has been done).
In all of my testing, I was only able to get a call to a dummy member on the base to cause the base to call its static constructor as illustrated:
class Base
{
static Base()
{
Console.WriteLine("Base static constructor called.");
}
internal static void Initialize() { }
}
class Derived : Base
{
static Derived()
{
Initialize(); //Removing this will cause the Base static constructor not to be executed.
Console.WriteLine("Derived static constructor called.");
}
public static void DoStaticStuff()
{
Console.WriteLine("Doing static stuff.");
}
}
class Program
{
static void Main(string[] args)
{
Derived.DoStaticStuff();
}
}
The other option was including a static read-only member in the derived typed that did the following:
private static readonly Base myBase = new Base();
This however feels like a hack (although so does the dummy member) just to get the base static constructor to be called.
I almost alway regret relying on something like this. Static methods and classes can limit you later on. If you wanted to code some special behavior for your Type class later you would be boxed in.
So here is a slight variation on your approach. It is a bit more code but it will allow you to have a custom Type defined later that lets you do custom things.
abstract class TypeBase
{
private static bool _initialized;
protected static void Initialize()
{
if (!_initialized)
{
Type<int>.Instance = new Type<int> {Name = "int"};
Type<long>.Instance = new Type<long> {Name = "long"};
Type<double>.Instance = new Type<double> {Name = "double"};
_initialized = true;
}
}
}
class Type<T> : TypeBase
{
private static Type<T> _instance;
public static Type<T> Instance
{
get
{
Initialize();
return _instance;
}
internal set { _instance = value; }
}
public string Name { get; internal set; }
}
Then later when you get to adding a virtual method to Type and want a special implementation for Type you can implement thus:
class TypeInt : Type<int>
{
public override string Foo()
{
return "Int Fooooo";
}
}
And then hook it up by changing
protected static void Initialize()
{
if (!_initialized)
{
Type<int>.Instance = new TypeInt {Name = "int"};
Type<long>.Instance = new Type<long> {Name = "long"};
Type<double>.Instance = new Type<double> {Name = "double"};
_initialized = true;
}
}
My advice would be to avoid static constructors - it is easy to do. Also avoid static classes and where possible static members. I am not saying never, just sparingly. Prefer a singleton of a class to a static.
Just an idea, you can do something like this:
abstract class TypeBase
{
static TypeBase()
{
Type<int>.Name = "int";
Type<long>.Name = "long";
Type<double>.Name = "double";
}
}
class Type<T> : TypeBase
{
static Type()
{
new Type<object>();
}
public static string Name { get; internal set; }
}
class Program
{
Console.WriteLine(Type<int>.Name);
}

what is the c# equivalent of static {...} in Java?

In Java I can write:
public class Foo {
public static Foo DEFAULT_FOO;
static {
DEFAULT_FOO = new Foo();
// initialize
DEFAULT_FOO.init();
}
public Foo() {
}
void init() {
// initialize
}
}
How can I get the same functionailty in C# (where static members are initialized before use)? And, if this is a bad thing to try to do, what is a better approach?
you use a static constructor, like this:
public class Foo
{
static Foo()
{
// inits
}
}
Here's more info.
Bottom line: it's a paramaterless constructor with the static keyword attached to it. Works just like the static block in Java.
Edit: One more thing to mention. If you just want to construct something statically, you can statically initialize a variable without the need for the static constructor. For example:
public class Foo
{
public static Bar StaticBar = new Bar();
}
Keep in mind that you'll need a static constructor if you want to call any methods on Bar during static initialization, so your example that calls Foo.Init() still needs a static constructor. I'm just sayin' you're not limited, is all. :)
Static is still the keyword in C#:
public class Foo {
public static Foo DefaultFoo;
static Foo {
DefaultFoo = new Foo();
// initialize
DefaultFoo.init();
}
public Foo() {
}
void init() {
// initialize
}
}

Categories

Resources