Подтвердить что ты не робот

С# Generic Static Constructor

Будет ли запущен статический конструктор для общего класса для каждого типа, который вы передаете в общий параметр, например:

 class SomeGenericClass<T>
 {
      static List<T> _someList;
      static SomeGenericClass()
      {
          _someList = new List<T>();
      }
 }

Есть ли обратная связь с использованием этого подхода?

4b9b3361

Ответ 1

Да статический конструктор будет вызываться один раз для каждого замкнутого типа класса (тип, созданный при указании параметров типа). См. спецификация С# 3, §10.12 Статические конструкторы.

Статический конструктор для замкнутого типа класса выполняется не более одного раза в заданном домене приложения.

а также:

Поскольку статический конструктор выполняется ровно один раз для каждого замкнутого построенного типа класса, это удобное место для принудительного выполнения проверок во время выполнения параметра типа, который нельзя проверить во время компиляции через ограничения (§10.1.5). Например, следующий тип использует статический конструктор для обеспечения того, чтобы аргумент типа был перечислением:

class Gen<T> where T: struct
{
    static Gen() {
        if (!typeof(T).IsEnum) {
            throw new ArgumentException("T must be an enum");
        }
    }
}

Также важно прочитать §4.4.2 Открытые и закрытые типы:

Во время выполнения весь код в объявлении общего типа выполняется в контексте замкнутого построенного типа, который был создан путем применения аргументов типа к объявлению общего типа. Каждый параметр типа в родовом типе привязан к определенному типу времени выполнения. Обработка во время выполнения всех операторов и выражений всегда происходит с закрытыми типами, а открытые типы встречаются только во время обработки времени компиляции.

Каждый замкнутый построенный тип имеет свой собственный набор статических переменных, которые не разделяются никакими другими замкнутыми построенными типами.

Эта программа, которую вы можете запустить, демонстрирует, что статический конструктор вызывается три раза, а не один раз:

public class Program
{
    class SomeGenericClass<T>
    {
        static SomeGenericClass()
        {
            Console.WriteLine(typeof(T));
        }
    }

    class Baz { }

    static void Main(string[] args)
    {
        SomeGenericClass<int> foo = new SomeGenericClass<int>();
        SomeGenericClass<string> bar = new SomeGenericClass<string>();
        SomeGenericClass<Baz> baz = new SomeGenericClass<Baz>();
    }
}

Вывод:

System.Int32
System.String
Program+Baz

Ответ 2

Он будет работать, но новый "экземпляр" будет создан для каждого используемого вами типа.

Ответ 3

Да, статические члены и конструкторы для общих типов специфичны для общего параметра и будут выполняться для каждого другого типа. Нет никаких реальных недостатков. Просто будьте осторожны при реорганизации не общего класса в общий.

Ответ 4

Да, он будет запускаться для каждого типа, который вы поставляете, потому что для каждого другого поставляемого типа вы получаете отдельный тип.