C# универсальный статический конструктор

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

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

Есть ли, кто-либо тянет спины к использованию этого подхода?

52
задан Seattle Leonard 29 May 2010 в 09:56
поделиться

4 ответа

Да, статический конструктор будет вызван один раз для каждого закрытого типа класса (тип, созданный при указании параметров типа). См. Спецификацию C# 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>();
    }
}

Output:

System.Int32
System.String
Program+Baz
62
ответ дан 7 November 2019 в 09:31
поделиться

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

2
ответ дан 7 November 2019 в 09:31
поделиться

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

0
ответ дан 7 November 2019 в 09:31
поделиться

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

0
ответ дан 7 November 2019 в 09:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: