[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