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
Just reference one of your static fields. This will force your static initialization code to run. For example:
public class MyClass
{
private static readonly int someStaticField;
static MyClass() => someStaticField = 1;
// any no-op method call accepting your object will do fine
public static void TouchMe() => GC.KeepAlive(someStaticField);
}
Usage:
// initialize statics
MyClass.TouchMe();
I'm not exactly sure what your use case is for this, but you can force static initializers to run in a fairly hacky way using partial classes and inner classes:
The idea is to use a partial outter class with a static field that accesses another static field on the inner class. When the outter class is statically initialized, the static field initialization will kick-off the static initialization of all the inner classes:
public partial class OutterClass
{
// When OutterClass is initialized, this will force InnerClass1 to be initialized.
private static int _innerClass1Touched = InnerClass1.TouchMe;
public static class InnerClass1
{
public static int TouchMe = 0;
static InnerClass1()
{
Console.WriteLine("InnerClassInitialized");
}
}
}
public partial class OutterClass
{
// When OutterClass is initialized, this will force InnerClass2 to be initialized.
private static int _innerClass2Touched = InnerClass2.TouchMe;
public static class InnerClass2
{
public static int TouchMe = 0;
static InnerClass2()
{
Console.WriteLine("InnerClass2Initialized");
}
}
}
Then, somewhere early in your application, you just need to reference OutterClass in a way that will result in static initialization, like constructing an instance of it.
A more realistic example might be...
public interface IService
{
void SayHello();
}
public partial class ServiceRegistry
{
private static List<Func<IService>> _serviceFactories;
private static void RegisterServiceFactory(Func<IService> serviceFactory)
{
// This has to be lazily initialized, because the order of static initialization
// isn't defined. RegisterServiceFactory could be called before _serviceFactories
// is initialized.
if (_serviceFactories == null)
_serviceFactories = new List<Func<IService>>();
_serviceFactories.Add(serviceFactory);
}
public List<IService> Services { get; private set; }
public ServiceRegistry()
{
Services = new List<IService>();
foreach (var serviceFactory in _serviceFactories)
{
Services.Add(serviceFactory());
}
}
}
// In another file (ServiceOne.cs):
public class ServiceOne : IService
{
void IService.SayHello()
{
Console.WriteLine("Hello from ServiceOne");
}
}
public partial class ServiceRegistry
{
// When OutterClass is initialized, this will force InnerClass1 to be initialized.
private static int _serviceOneRegistryInitializer = ServiceOneRegistry.Initialize;
private static class ServiceOneRegistry
{
public static int Initialize = 0;
static ServiceOneRegistry()
{
ServiceRegistry.RegisterServiceFactory(() => new ServiceOne());
}
}
}
// In another file (ServiceTwo.cs):
public class ServiceTwo : IService
{
void IService.SayHello()
{
Console.WriteLine("Hello from ServiceTwo");
}
}
public partial class ServiceRegistry
{
// When OutterClass is initialized, this will force InnerClass1 to be initialized.
private static int _serviceTwoRegistryInitializer = ServiceTwoRegistry.Initialize;
private static class ServiceTwoRegistry
{
public static int Initialize = 0;
static ServiceTwoRegistry()
{
ServiceRegistry.RegisterServiceFactory(() => new ServiceTwo());
}
}
}
static void Main(string[] args)
{
ServiceRegistry registry = new ServiceRegistry();
foreach (var service in registry.Services)
{
serivce.SayHello();
}
// Output will be:
// Hello from ServiceOne
// Hello from ServiceTwo
// No guarantee on order.
}
Why even do this? It has a very narrow use-case. It eliminates the need to have a single method that initializes and registers all the services. The case in which I personally want to eliminate that single method initialization is for code generation purposes.
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.
Also you can do this:
type.TypeInitializer.Invoke(null, null);