[Mono-list] Static constructor issue

Jonathan Pryor jonpryor at vt.edu
Thu Sep 7 22:00:38 EDT 2006


On Thu, 2006-09-07 at 23:40 +0200, Kornél Pál wrote:
> Just to make sure that everything is clear:
> 
> Static constructors are not part of inheritance. Static constructors are 
> called when you access the class that declares the static constructor. The 
> reason because static constructors are called in "reverse order" is because 
> the static constructor is executed before the constructor of the child class 
> calls its parent's constructor, in other words: when it's is used for the 
> first time.
> 
> So there is nothing special with static constructors. They are simply 
> executed before their first member is accessed.

And to further muddy the waters... :-)

There are two types of classes as far as static constructor invocation
is concerned: those with `beforefieldinit' set, and those without.

If `beforefieldinit' is set, then not only can the class' static
constructor be "executed before [the] first member is accessed," but it
can be _way_ before the first member is accessed.  Like at program
startup, _hours_ before any member is accessed.

`beforefieldinit' is enabled by default.  You disable it by manually
writing a static constructor.

So this type will have beforefieldinit set:

	class SetsBeforeFieldInit {
		public static int Foo = 42;
	}

While this type will _not_ have beforefieldinit set:

	class DoesNotSetBeforeFieldInit {
		public static int Foo;

		static DoesNotSetBeforeFieldInit ()
		{
			Foo = 42;
		}
	}

beforefieldinit is a performance advantage: it allows the JIT inliner to
invoke the static constructor during JIT time, instead of needing to
delay static constructor invocation until just before a member is
accessed.  It's also useful for --aot code, as the initialization
performed by the static constructor could be cached (in some principal)
within the AOT code.

beforefieldinit also has a disadvantage: if the constructor for a static
member has a dependency on some other library, and that other library
hasn't been initialized yet, then early invocation of the static
constructor will be in error, e.g.

	class Foo {
		public static Pixbuf Icon = new Pixbuf ("filename");
	}

If the `Pixbuf' constructor requires that Gtk# be initialized, this use
_may_ fail if the Foo static constructor is invoked before Gtk# is
initialized.  This will be hell to debug. :-/

See also

http://tirania.org/blog/archive/2006/Apr-19.html
http://www.yoda.arachsys.com/csharp/beforefieldinit.html

 - Jon




More information about the Mono-list mailing list