После отладки особенно сложной проблемы в VB.NET с участием порядка, в котором инициализируются переменные экземпляра, я обнаружил, что существует разрывное несоответствие между поведением, которое я ожидал от С#, и фактическим поведением в VB.NET.
Nota bene: Этот вопрос касается небольшого несоответствия в поведении VB.NET и С#. Если вы являетесь фанатом языка, который не может предоставить ответ, отличный от того, "почему вы должны использовать С#, noob", вам здесь нечего видеть; добро пожаловать.
В частности, я ожидал поведения, описанного в С# Language Specification (выделено мной):
Когда конструктор экземпляра не имеет инициализатора конструктора или имеет инициализатор конструктора формы
base(...)
, этот конструктор неявно выполняет инициализации, указанные инициализаторами переменных полей экземпляров, объявленных в его классе. Это соответствует последовательности назначений, которые выполняются сразу после входа в конструктор и перед неявным вызовом конструктора прямого базового класса. Инициализаторы переменных выполняются в текстовом порядке, в котором они отображаются в объявление класса.
Сравните это с частью Спецификации языка VB.NET, относящейся к Instance Constructors, в которой говорится (выделено мной):
Когда первый оператор конструктора имеет вид
MyBase.New(...)
, конструктор неявно выполняет инициализации, указанные инициализаторами переменных переменных экземпляра, объявленных в типе. Это соответствует последовательности назначений, которые выполняются сразу после вызова конструктора прямого базового типа. Такое упорядочение гарантирует, что все базовые переменные экземпляра инициализируются их инициализаторами переменных до того, как все операторы, имеющие доступ к экземпляру, будут выполняется.
Несоответствие здесь сразу становится очевидным. С# инициализирует переменные уровня класса перед вызовом базового конструктора. VB.NET делает именно обратное, по-видимому, предпочитая вызывать базовый конструктор перед установкой значений полей экземпляра.
Если вы хотите увидеть какой-то код, этот связанный вопрос дает более конкретный пример расходящегося поведения. К сожалению, он не дает никаких указаний о том, как можно заставить VB.NET следовать модели, установленной С#.
Меня меньше интересует, почему дизайнеры двух языков выбрали такие расходящиеся подходы, как я в возможных обходных решениях этой проблемы. В конечном счете, мой вопрос следующий: Есть ли способ, которым я могу написать или структурировать свой код в VB.NET, чтобы принудительно инициализировать переменные экземпляра до того, как конструктор базового типа называется, а также стандартный поведение в С#?