Нужно ли вызывать базовый конструктор структур?

1,00
р.
Троелсен пишет:
На заметку! Вы наверняка заметили в конструкторах Square и Rectangle связывание в цепочку со стандартным конструктором. Причина в том, что при наличии структуры, которая использует синтаксис автоматических свойств (как в данном случае), стандартный конструктор должен быть явно вызван (из всех специальных конструкторов) для инициализации закрытых поддерживающих полей. Да, это весьма своеобразное правило C#, но, в конце концов, ведь данная глава посвящена сложным темам.
И приводит в пример такой код:
public struct Rectangle { public int Width { get set } public int Height { get set } public Rectangle(int w, int h) : this() { Width = w Height = h } public void Draw() { for (int i = 0 i < Height i++) { for (int j = 0 j < Width j++) { Console.Write("*") } Console.WriteLine() } } public override string ToString() { return string.Format("[Width = {0} Height = {1}]", Width, Height) } }
public struct Square { public int Length { get set } public Square(int i) : this() { Length = 1 } public void Draw() { for (int i = 0 i < Length i++) { for (int j = 0 j < Length j++) { Console.Write("*") } Console.WriteLine() } } public override string ToString() { return string.Format("[Length = {0}]", Length) } public static explicit operator Square(Rectangle r) { Square s = new Square() s.Length = r.Height return s } }
Немного, не понимаю, зачем нужно вызывать базовый конструктор структур? Попробовал в дебаггере и так, и так вызвать и разницы не заметил...

Ответ
C# 5 и ниже:
Дело в том, что параметр this для конструктора структуры ведёт себя так, как если бы был определён как out S this, что означает, что this не является определённо присвоенным, в терминологии спецификации C#, в момент входа в конструктор. В то время как для прочих методов структур параметр this ведёт себя как ref S this.
Переменную, которая не является определённо присвоенной, нельзя передавать в методы в качестве параметра ни по значению, ни по ссылке. Получается, что вы не можете вызывать метод назначения свойства (CS0188) до того, как присвоите значения всем полям структуры в конструкторе.
Для автоматически реализованных свойств компилятор создаёт скрытое резервное поле для хранения значения, но дотянутся непосредственно до этого поля в пользовательском коде невозможно. Получается, что в конструкторе Вы не можете вызвать метод назначения автоматически реализованного свойства, пока не присвоите резервному полю какое-либо значение.
Получается замкнутый круг: чтобы назначить значение скрытому резервному полю, надо вызвать метод назначения свойства, но метод назначения свойства нельзя вызывать пока скрытому резервному полю не присвоено значение. Вызов конструктора по умолчанию используется для того, чтобы этот круг разорвать.
C# 6
В C# 6 сделано послабление: в конструкторе разрешено вызывать методы назначения для автоматически реализованных свойств, пока this не является определённо присвоенным, а также методы чтения для свойств, которые являются определённо присвоенными. Послабление не касается свойств с кодом пользователя. Обращение к ним по прежнему считается вызовом метода и недопустимо до полной инициализации this.