будет ли компилятор добавлять статический конструктор по умолчанию в c # - PullRequest
0 голосов
/ 09 января 2019

Обычно компилятор добавляет конструктор по умолчанию, когда мы не объявляем конструктор явно. Таким же образом он также выделяет статический конструктор по умолчанию. Если нет, то почему? Если да, то почему? и в какой ситуации?

Ответы [ 4 ]

0 голосов
/ 10 января 2019

Да. Только в одном случае: Когда класс или структура имеют статическую переменную, настроенную на пользовательские значения по умолчанию (скажем, static int age = 18;). В этом конкретном случае статический конструктор по умолчанию добавляется в код IL. Кроме этого случая не будет области действия статического конструктора по умолчанию.

0 голосов
/ 09 января 2019

Нет, в C # нет автоматически генерируемых статических конструкторов.

Компилятору не нужно создавать автоматический статический конструктор - единственные элементы, которые могут нуждаться в инициализации в статическом конструкторе, - это статические поля / свойства, но инициализация происходит вне статического конструктора. Это не относится к конструктору экземпляров, потому что вам нужен конструктор, чтобы иметь возможность создавать экземпляр (если это не статический класс) - поэтому компилятор должен был создать его, если он не указан.

Инициализация статического поля :

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

Дополнительную информацию можно найти, например, в разделе Классы проекта спецификации C # 6.0. В частности, вы можете видеть, что Конструкторы по умолчанию явно вызывают автоматически при условии:

Если класс не содержит объявлений конструктора экземпляра, автоматически предоставляется конструктор экземпляра по умолчанию.

while Статические конструкторы не имеют никакой информации о том, что он "автоматически предоставляется".

0 голосов
/ 10 января 2019

Если вы не предоставляете конструктор для своего класса, C # по умолчанию создает его, который создает экземпляр объекта и устанавливает для переменных-членов значения по умолчанию, перечисленные в таблице значений по умолчанию. Конструктор без каких-либо параметров называется конструктором по умолчанию. Другими словами, этот тип конструктора не принимает параметры. Недостаток конструктора по умолчанию заключается в том, что каждый экземпляр класса будет инициализирован одинаковыми значениями, и невозможно инициализировать каждый экземпляр класса разными значениями.

Конструктор по умолчанию инициализирует:

Все числовые поля в классе равны нулю. Все строковые и объектные поля равны нулю.

0 голосов
/ 09 января 2019

Вы и @mjwills правы. При отсутствии явно определенного конструктора экземпляра он будет автоматически создан CLR , см. 10.11.4 спецификации языка C #. , поэтому эти два класса равны (кроме имени курса) в IL:

class A1 { }
class A2 { public A2() : base() { } }

Вы можете проверить, есть ли какой-либо статический конструктор в классе, например: typeof(A1).TypeInitializer, или, точнее, typeof(A1).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).

Итак, давайте сделаем несколько простых проверок:

class A { }
typeof(A).TypeInitializer == null // true
typeof(A).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).Length == 0 // true

class B { static B { } }
typeof(B).TypeInitializer != null // true
typeof(B).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).Length == 1 // true

Однако, если вы используете инициализаторы статических полей или свойств, CLR добавит вам статический конструктор по умолчанию:

class C { public static int I = 1; }
typeof(B).TypeInitializer != null // true
typeof(B).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).Length == 1 // true

class D { public static int P { get; set; } = 1; }
typeof(B).TypeInitializer != null // true
typeof(B).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).Length == 1 // true

Еще одна проверка без инициализаторов полей и свойств:

class E { public static int I; public static int P { get; set; } }
typeof(E).TypeInitializer == null // true
typeof(E).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).Length == 0 // true
...