How do static constructors work for generic types?

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 really don't understand how this compiles.

  • When does the static constructor start?
  • Why can I use generic types in static members?
  • What types are supposed to apply?
+6
source share
4 answers
  • A static constructor is needed at the first moment. The exact time is a bit more complicated, because if in binary format flags like beforefieldinit ; you probably don't need to worry too much about the details, except that it starts when the first access class is accessed before it is needed.

  • Well, why not? :) Each type of form EventSystemBase<T, K> is its own separate class and is not related to other common instances of the class, so the constructor must be run for each of them. They all differ from runtime in every way.

  • The static constructor works for the "cooked" type, and not for the "raw" type (that is, it runs for the version with replaced generic types), so there is no real problem here.

* In fact, the runtime avoids creating duplicate instances of generic types of a reference type. But it doesnโ€™t matter here, to the programmer or program.

+7
source

A static constructor is not for an open generic type. It will only work if you specify type parameters, for example, EventSystemBase<MyEvent, MyAutoEvent> , which is actually a different class than, for example, EventSystemBase<AnotherEvent, MyAutoEvent> with its own static constructor. In each case, the static constructor is executed before the first instance of this separate class or a reference to its static elements is created.

+2
source

If it applies the same from my knowledge in C ++ that day ...

Generics are generated at compile time , and they are converted to many separate and different classes. For each of these classes, the static constructor works before any code references the static class. The CLR knows which types are referenced because each of the classes is unique.

EventSystemBase <string, byte> has absolutely no relationship with EventSystemBase <string, int>. It is as if you wrote two completely different classes in the source code.

 class Program { public static void Main() { var myInt = new MyGeneric<int>(); myInt.InstanceMethod(); MyGeneric<int>.StaticMethod(); MyGeneric<long>.StaticMethod(); var myLong = new MyGeneric<long>(); myLong.InstanceMethod(); Console.ReadLine(); } } public class MyGeneric<T> { static MyGeneric() { Console.WriteLine("Static constructor: {0}", typeof(T).Name); } public static void StaticMethod() { Console.WriteLine("Static method: {0}", typeof(T).Name); } public void InstanceMethod() { Console.WriteLine("Instance method: {0}", typeof(T).Name); } } 
0
source
  • The static constructor in generic is called every time you call another <T, K> common class.

2-3. with 1, it should be clear, it is released to T, K generic

0
source

Source: https://habr.com/ru/post/885693/


All Articles