Search code examples
c#generics

How do static constructors for generic types work?


public abstract class EventSystemBase<T, K> : IAutoEvent
    where T : Event
    where K : IAutoEvent, new()
{
    public static T Instance { get { return EventSystem.Events.OfType<T>().FirstOrDefault(); } }
    public static IAutoEvent AutoEventInstance { get { return new K(); } }

    static EventSystemBase()
    {
        EventBot.Register(new EventBotEntry(Instance.Name, AutoEventInstance));
    }

    [...]
}

I don't really understand how this compiles.

  • When does the static constructor run?
  • Why can I use generic types in static members?
  • How is it supposed to know which types to apply?

Solution

    • The static constructor is at the first moment it is needed. The exact timing is a bit tricky because if flags like beforefieldinit in the binary; you probably don't need to worry too much about the details except that it's run when the first class member is accessed, before it is needed.

    • Well, why not? :) Every type of the form EventSystemBase<T, K> is its own separate class and bears no relation to the other generic instances of the class, so the constructor needs to run for each one. They're all different to the runtime in all* respects.

    • The static constructor runs for a "cooked" type and not the "raw" type (i.e. it runs for the version with the generic types substituted), so there's no real problem here.

    *Actually, the runtime avoids creating duplicate instances of reference type generics. But that doesn't matter here, to the programmer or to the program.