Tech Off Thread

8 posts

Static initializers and reflection

Back to Forum: Tech Off
  • User profile image
    BitFlipper

    So if you have a class that contains static fields, there is a static method that gets called to initialize these fields at startup (before any class instances are created). If you look at the IL, the method looks like this:

      .method private hidebysig specialname rtspecialname static 
              void  .cctor() cil managed
      {
        // Code size       11 (0xb)
        .maxstack  8
        .line 25,25 : 9,42 ''
        IL_0000:  ldc.i4     0x3039
        IL_0005:  stsfld     int32 TestIL.TestClass1::m_int
        .line 16707566,16707566 : 0,0 ''
        IL_000a:  ret
      } // end of method TestClass1::.cctor

    My question is, how can one get this method via reflection at runtime?

     

  • User profile image
    Dexter

    You can use Type.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic) and select the one where IsStatic is true.

  • User profile image
    BitFlipper

    ,Dexter wrote

    You can use Type.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic) and select the one where IsStatic is true.

    Ah excellent! I thought I tried that already, but I just tried it again and got it working.

  • User profile image
    BitFlipper

    A related question...

    Let's say I'm writing a compiler that takes IL and compiles it to some native code. At runtime, would it be enough to call all static contructors of all classes to ensure that static fields are properly initialized (does order matter?), or is there something else that needs to be executed as well (in addition to the assembly's EntryPoint)?

    So basically:

    1. Call all static constructors
    2. Call Assembly.EntryPoint
  • User profile image
    Dexter

    Calling all static constructors before calling entry point can be inefficient if there are a lot of them. More importantly, if you want to call all static constructors at startup you'll find that there's no particular ordering you can use.

    The basic requirement is that the static constructor (aka type initialized) of a type is called before any of the static fields of that type are accessed. This lazy initialization generates a particular ordering that you cannot reproduce at statup without some complicated or even impossible code analysis.

    You can read more details about this in section 10.5.3 of the ECMA-335 standard (http://www.ecma-international.org/publications/standards/Ecma-335.htm).

  • User profile image
    BitFlipper

    @Dexter:

    In my case the number of static fields will be minimal so I don't think it should be a problem to just call them all.

    Although, this lazy initialization... How would that work in cases like this:

    private static DateTime initTime =  DateTime.Now;

    ...or cases where the static field is something that does real work, like a class that creates a file in its constructor, etc? Some other class instance might need to use that file. A bit of a contrived example, but still...

  • User profile image
    Dexter

    @BitFlipper: Those cases are the developer's problem. Since the specification doesn't require that all static ctors are called at startup it's obvious that one should not depend on such behavior.

  • User profile image
    BitFlipper

    @Dexter:

    OK thanks, that makes sense. Basically it is a non-issue.

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.