Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?
like image 810
bevacqua Avatar asked Apr 12 '11 01:04

bevacqua


2 Answers

  • 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.

like image 191
user541686 Avatar answered Sep 29 '22 15:09

user541686


The static constructor isn't for the open generic type. It will only run when you have specified the type paramaters, e.g., EventSystemBase<MyEvent, MyAutoEvent>, which is actually a different class than e.g., EventSystemBase<AnotherEvent, MyAutoEvent> with its own static constructor. In each case, the static constructor runs before the first instance of that separate class is created or any of its static members are referenced.

like image 43
Mark Cidade Avatar answered Sep 29 '22 16:09

Mark Cidade