День сто девяносто второй. #ЗаметкиНаПолях
Заметки по обобщённым типам
1. Инициализация и состояния обобщённых типов
Если выполнить следующий код:
1. Значение
2. Статический конструктор запускается дважды: один раз для каждого закрытого составного типа. Если бы статического конструктора не было, было бы меньше гарантий того, когда точно происходит инициализация каждого типа. Но можно однозначно сказать, что вы можете рассматривать
Источник: Jon Skeet “C# In Depth”. 4th ed – Manning Publications Co, 2019. Глава 2.
Заметки по обобщённым типам
1. Инициализация и состояния обобщённых типов
Если выполнить следующий код:
Console.WriteLine(typeof(List<int>));На экран выведется следующее:
Console.WriteLine(typeof(List<string>));
System.Collections.Generic.List`1[System.String]List`1 означает обобщённый тип List арности 1 (один параметр типа), а аргументы параметра типа указаны в квадратных скобках. Таким образом,
System.Collections.Generic.List`1[System.Int32]
List<int>
и List<string>
- это фактически разные типы, которые созданы из одного и того же определения обобщённого типа List<T>
. Они называются закрытыми составными типами (closed, constructed type). Это относится не только к тому, как типы используются, но и к тому, как они инициализируются и как обрабатываются статические поля. Каждый закрытый составной тип инициализируется отдельно и имеет собственный независимый набор статических полей. Следующий листинг демонстрирует это с помощью простого обобщённого счетчика.class GenericCounter<T>…
{
private static int value;
static GenericCounter()
{
Console.WriteLine("Инициализация счётчика для {0}", typeof(T));
}
public static void Increment()
{
value++;
}
public static void Display()
{
Console.WriteLine("Счётчик для {0}: {1}", typeof(T), value);
}
}
GenericCounter<string>.Increment();Вывод будет следующим:
GenericCounter<string>.Increment();
GenericCounter<string>.Display();
GenericCounter<int>.Display();
GenericCounter<int>.Increment();
GenericCounter<int>.Display();
Инициализация счётчика для System.StringИз этого можно сделать два вывода:
Счётчик для System.String: 2
Инициализация счётчика для System.Int32
Счётчик для System.Int32: 0
Счётчик для System.Int32: 1
1. Значение
GenericCounter<string>
не зависит от GenericCounter <int>
. 2. Статический конструктор запускается дважды: один раз для каждого закрытого составного типа. Если бы статического конструктора не было, было бы меньше гарантий того, когда точно происходит инициализация каждого типа. Но можно однозначно сказать, что вы можете рассматривать
GenericCounter<string>
и GenericCounter<int>
как независимые типы.Источник: Jon Skeet “C# In Depth”. 4th ed – Manning Publications Co, 2019. Глава 2.