The Type initializer for '{0}' threw an exception - oder warum die Reihenfolge statischer Felder nicht egal ist...

Heute hab ich in einem Projekt meine Klassen etwas aufgeräumt und dabei auch die Reihenfolge der Methoden, Eigenschaften und Variablen angepasst. Der Build des Projekts war erfolgreich - die Tests danach aber nicht. Es erschien der Fehler:

The Type initializer for ‘{0}’ threw an exception.

Da ich mir aber sicher war, dass ich wirklich nur Elemente auf Klassenebene verschoben hab, hat mich das wirklich sehr verwundert… Aus dem StackTrace konnte man entnehmen, dass es sich um den statische Konstruktor (.cctor()) handelt. Nun, ich schreibe häufig statische Konstruktoren, aber in aller Regel ohne jeglichen Inhalt, weswegen der Grad der Verwunderung dementsprechend stieg.

Kurzum, der Fehler liegt wirklich an der Reihenfolge, allerdings geht es hierbei ausschließlich um statische Felder, die in der richtigen Reihenfolge definiert sein müssen. Bei genauerer Betrachtung ist das auch nur logisch. Ich hätte mir an der Stelle eine schöne Kompiler-Fehlermeldung gewünscht.

Ein einfaches Beispiel zeigt, worum es genau geht.

1
2
3
4
5
6
public class Test {
private static readonly decimal x = 1 / y;
private static readonly int y = 8;
static Test() { }
}

Sobald eine Instanz der Klasse erstellt wird, kommt es zu einer Division durch 0 (bzw. zum Versuch desselben) und damit zu besagter Ausnahme.
Zur Veranschaulichung hier noch das Äquivalent. y ist bei der ersten Verwendung noch mit dem default-Wert belegt - und der ist nunmal 0.

1
2
3
4
5
6
7
8
9
public class Test {
private static readonly decimal x;
private static readonly int y;
static Test() {
x = 1 / y;
y = 8;
}
}

Damit ist aber auch klar, dass man die Initialisierung statischer Variablen innerhalb des statischen Konstruktors selbst vornehmen sollte - zumindest wenn diese von anderen Variablen abhängen.