Generic static fields initialization - c#

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.

Related

Accessing Static Members of Static Members

Consider the following classes
class A
{
public static int i;
}
class B
{
public static A a{get;}=new A(); // without new A(), B.A will be null
}
now,
B.a gives a new instance of A and since the variable "i" of class A is static, I can not access "i" through B.a i.e B.a.i is compile time error.
I understand that if I do like below,
class B
{
static class A
{
static int i;
}
}
then I could do B.A.i.
So my question is how could I access static members of a static member of a class? Is it possible at all and is there any other pattern that I can use.
Also note that making class "A" as static and having class "B" as
class B
{
public static A a{get;}
}
gives a compile time error that "static type cannot be used as return type".
Since i is static member of A you can access it directly like
class B
{
public static A a {get;} = new A();
public int ii{get;} = A.i;
}
how could I access static members of a static member of a class?
If something is a member of a class -- static or not static -- that means it's either a value or a reference to an instance of something. Therefore, if you know you have an instance of a class but that class has static members itself, then just access those members statically:
class MyClass
{
public static string Value { get; }
}
string x = MyClass.Value;
You don't need to instantiate a class to access it's static members.
Simply you can try :
int value = A.i;
If you need, you can add a static class too :
public static class A
{
public static int i;
}
and you can use anywhere in your code like :
int value = A.i;

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.

Still confused with BeforeFieldInit

According to MSDN:
BeforeFieldInit specifies that calling static methods of the type does not force the
system to initialize the type.
In addition to this (IMHO), the existence of static ctor will disable BeforeFieldInit.
Now I want to check whether the type is not initialized if I invoke static method while my class has no static ctor as follows.
using System;
namespace Static
{
class Foo
{
public Foo(string arg)
{
Console.WriteLine("Foo's ctor called by {0}.", arg);
}
}
class Goo
{
Foo f2 = new Foo("Goo's instance field.");
//static Goo()
//{
// Console.WriteLine("Goo's static ctor.");
//}
static Foo f = new Foo("Goo's static field.");
public Goo()
{
Console.WriteLine("Goo's default ctor.");
}
public static void Display()
{
Console.WriteLine("Goo's static method.");
}
}
class Program
{
static void Main(string[] args)
{
Goo.Display();
Console.ReadKey();
}
}
}
And the output is as follows,
Foo's ctor called by Goo's static field..
Goo's static method.
Questions
Why does the static field still get initialized when I invoke a static method? It seems to be inconsistent with MSDN says above.
Goo has a static constructor(created by complier).
In CLI spec:If marked BeforeFieldInit then the type’s initializer method is
executed at, or sometime before, first access to any static field
defined for that type.

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 exactly are Static Constructor in 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();
}
}

Categories

Resources