How to initialize a C# static class before it is actually needed?

后端 未结 5 1369
北海茫月
北海茫月 2021-02-05 10:54

I have a static class with a static constructor that takes some time (10-15 seconds) to execute and fully initialize the class. In order to improve performance, I\'ve decided to

相关标签:
5条回答
  • 2021-02-05 11:09

    I'm not sure if you can specify when a static constructor is loaded.

    From MSDN "A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced."

    http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx

    *EDIT: * Would adding the singleton pattern help here? The getter can call Initialize() by checking a flag in the class, IsLoaded=true. Subsequent calls will not call Initialize()

    0 讨论(0)
  • 2021-02-05 11:09

    Two work-arounds:

    1. Move the constructor code to Initialize() so you can call explicitly. And replace the code inside the constructor to just call the Initialize() method in case the static class is loaded dynamically before you've called it explicitly

      public static class StaticClass
      {
          // actual constructor
          static StaticClass()
          {
              Initialize();
          }
      
          // explicit "constructor"
          public static void Initialize()
          {
              MyProperty = "Some Value";
          }
      
          public static string MyProperty { get; set; }
      
      }
      

      Then initialize like this if you want:

      StaticClass.Initialize();
      

      Or it will be dynamically initialized the first time it's used

    2. Not as semantically pristine, but you can trigger the organic initialization of a static class just by consuming a property and throwing it in a temporary variable.

      So just do this:

      // trigger static initilaization
      var dummy = StaticClass.MyProperty;
      

      Still allows you to call it whenever you need to, but if there is some performance cost on initialization, you can try to invoke it on startup, rather than the first time the user does something that fires that code.

    For another helpful outline of static initialization see: Is the order of static class initialization in C# deterministic?

    0 讨论(0)
  • 2021-02-05 11:13

    The approach doesn't seem icky to me. I might name the method Touch(), give it an empty body, and add an appropriate comment. Would that be sufficient to get you over your feeling that something doesn't feel right about this?

    0 讨论(0)
  • 2021-02-05 11:21

    I would go with the initialize method (EDIT: See Jon's answer). But if you really just want to use the constructor, you can do this:

    var type = typeof (YourType);
    System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
    

    RunClassConstructor allows you to force the class constructor (static constructor) to run if it already hasn't. If it has already run, say because you used a static member of the class, then this has no effect. Running it additional times has no effect.

    0 讨论(0)
  • 2021-02-05 11:22

    I would probably just go for the Initialize method - and it can do something useful:

    • It can log that you're explicitly trying to initialize the class, with a stack trace
    • It might throw an exception if the class is already initialized via another Initialize call
    • You could possibly (with a bit of effort and reorganization) sort things so that any exceptions caused during initialization were propagated without the TypeInitializationException which you'd normally get.
    0 讨论(0)
提交回复
热议问题