Reputation: 13457
class Bus<T>
{
static Bus()
{
foreach(FieldInfo fi in typeof(T).GetFields())
{
if(fi.FieldType == typeof(Argument))
{
fi.SetValue(typeof(T), new Argument("busyname", "busyvalue"));
}
}
}
}
class Buss : Bus<Buss>
{
public static Argument field;
}
Any ideas how to make this work so that a reference to the static field in Buss triggers the static constructor in Bus?
Upvotes: 6
Views: 7662
Reputation: 26446
The static constructor of a generic type is invoked exactly once per Type
, when that type is referenced.
Calling Buss x = new Buss()
will invoke the static constructor of Bus<Buss>
.
Calling Bus<Buss> x = new Bus<Buss>()
will also invoke the static constructor of Bus<Buss>
, but it will do so for it's type argument Buss
, setting Buss.field
.
If you create a class Bugs : Bus<Buss>
it will never set Bugs.field
, as it will first resolve the type argument Buss
, which invokes the static constructor of it's base class Bus<Buss>
, setting Buss.field
. When it tries to call the static constructor of Bugs
base class, it will think it had already invoked the static Bus<Buss>
constructor and skip it.
Basically if I copy paste your code, create a dummy Argument
class and create a new instance of Buss
, the static constructor is invoked and Buss.field
is set to an instance of Argument
, but I do recognize some strange behavoir here in which I'd have to advise not to use reflection from a static method to reach subclasses' statics.
The example you provided only works because Buss
is the type argument for itself.
Upvotes: 2
Reputation: 4180
MSDN says that 'Static constructors are not inherited'. I guess this is similar to static fields which are not inherited either.
Upvotes: 1
Reputation: 86124
The fact that this matters to you probably means that you are using static constructors wrong.
With that in mind, you could make a static constructor in Buss
that manually invokes the static constructor in Bus
. Note that it's not possible to run a static constructor more than once.
Upvotes: 3