views:

359

answers:

7

I'd like to execute the static constructor of a class (i.e. I want to "load" the class) without creating an instance. How do I do that?

Bonus question: Are there any differences between .NET 4 and older versions?

Edit:

  • The class is not static.
  • I want to run it before creating instances because it takes a while to run, and I'd like to avoid this delay at first access.
  • The static ctor initializes private static readonly fields thus cannot be run in a method instead.
A: 

Static classes do not have constructors. What do you need to "load" ?

AndyC
Not true - you can have static constructors in c# http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx
Dan Diplo
Both static and non-static classes can have static constructors.
Marc Gravell
Neat! You learn something new every day on here! :)
AndyC
+1  A: 

The static constructor runs automatically the first time you access the class. There is no need (or capability) to 'run' it yourself.

Ray
Not *quite* true... it can run later: http://msmvps.com/blogs/jon_skeet/archive/2010/01/26/type-initialization-changes-in-net-4-0.aspx
Marc Gravell
I am constantly amazed by the number of obscure language features which I have never heard of, will probably never intentionally use, but which will probably bite me in the ass because I am not aware of them...
Ray
I want to run it earlier because it takes a long time (see edited question).
mafutrct
makes sense - create a "load()" method on your static class and call it whenever you want to. Just be sure to using locking and flags (or whatever) if necessary so it doesn't get loaded multiple times.
Ray
@Ray: A load method can't initialize readonly fields though. :\
mafutrct
As Mick Jagger once said: "you can't always git what you want" - how about using private static members with public static 'get' properties?
Ray
@Ray: Possible workaround, but I specifically asked this question because I wanted to avoid that.
mafutrct
Cool - I like Fabio's no-op method idea. Reading any property (even to throw away the value) would work too.
Ray
+3  A: 

There is no need to do this, the whole point of a static constructor is that it runs once when the class is first initialised at first access. If you want to run something on demand, then consider adding your initialisation code into a public method that is called by the constructor. You can then call this method whenever you like. But I'm not sure why you would want to do this?

Dan Diplo
This fails in my case because there are `static readonly` fields.
mafutrct
A: 

As others have said, static constructors run automatically. If you need to be explicit, maybe you should refactor it into a static method which you can run explicitly?

Explicitly calling a static method would also, of course, ensure that the static constructor had been executed.

edit

Static constructors are run when any static members are referenced. You could simply create a dummy method called initialize which did nothing but ensure that the framework calls the static constructor.

Gabe Moothart
(see edits in OP)
mafutrct
See comments to Ray's answer about the dummy method.
mafutrct
+3  A: 

Just reference one of your static fields. This will force your static initialization code to run. For example:

public class MyClass {
  private static readonly someStaticField;

  static MyClass() { someStaticField = ... }

  // any no-op method call accepting your object will do fine
  public static void TouchMe() { Equals(someStaticField, null); }
}

Usage:

// initialize statics
MyClass.TouchMe();
Fábio Batista
+1  A: 

The cctor (static constructor) will be called whenever one of the following occurs;

  1. You create an instance of the class
  2. Any static member is accessed
  3. Any time before that if BeforeFieldInit is set

If you want to explicitly invoke the cctor, assuming you have other static members, just invoke/access them.

If you are not doing anything very interesting in your cctor, the compiler may decide to mark it BeforeFieldInit, which will allow the CLR the option to execute the cctor early. This is explained in more detail here: http://blogs.msdn.com/davidnotario/archive/2005/02/08/369593.aspx

csauve
+2  A: 

The other answers are excellent, but if you need to force a class constructor to run without having a reference to the type (ie. reflection), you can use:

Type type = ...;
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
Gary Linscott
Does that run the _static_ ctor? The class does not have a public constructor. Also, is this safe in that it does not cause a ctor to run twice, possibly?
mafutrct
Yes, it runs the static ctor. It is also safe, the CLR will only let the static ctor be executed once.
Gary Linscott
Indeed, this method is explicitly provided for compiler writers to ensure deterministic initialization: http://blogs.msdn.com/cbrumme/archive/2003/04/15/51348.aspx
Ruben
Interesting. But cbrumme does not seem to explicitly state that the cctor gets called executed once, or did I miss that? I do like this solution, but I'd like to get this guaranteed before I accept.
mafutrct
Followup question: http://stackoverflow.com/questions/2658561
mafutrct