Что здесь происходит? Как я могу вызвать конструктор по умолчанию, когда его нет?
С учетом следующего кода:
public struct Foo
{
public Foo(int bar, int baz) : this()
{
Bar = bar; // Err 1, 2
Baz = baz; // Err 3
}
public int Bar { get; private set; }
public int Baz { get; private set; }
}
Что делает : this()
на самом деле? Нет конструктора по умолчанию, так что он звонит? Без этого добавления все происходит с ошибками.
Error 1 The 'this' object cannot be used before all of its fields are assigned to
Error 2 Backing field for automatically implemented property 'Foo.Bar' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.
Error 3 Backing field for automatically implemented property 'Foo.Baz' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.
Ответы
Ответ 1
Итак, почему конструктор struct без аргументы не разрешены в С#? Это потому что структуры уже содержат конструктор по умолчанию, который не имеет аргументы. Имейте в виду, что это конструктор по умолчанию является частью .Net, поэтому это не видимый в нашем коде. Единственная цель конструктора по умолчанию - присваивать значения по умолчанию своим членам.
В принципе, все структуры имеют конструктор по умолчанию. Ситуация будет отличаться от класса.
Ответ 2
Когда вы используете ярлык для свойств, вы можете получить доступ к свойствам только через свои сеттеры и получатели. Однако, прежде чем все поля были назначены, вам не разрешено вызывать какие-либо сеттеры. Обходным путем для этого является вызов конструктора без параметров, который создается автоматически, который инициализирует поля. Это, конечно, означает, что вы дважды инициализируете поля.
Когда я столкнулся с этой проблемой несколько дней назад, я просто удалил ярлык для свойств и сам объявил локальные переменные, чтобы я мог установить их в конструкторе:
public struct Foo {
public Foo(int bar, int baz) {
_bar = bar;
_baz = baz;
}
private int _bar, _baz;
public int Bar { get { return _bar; } }
public int Baz { get { return _baz; } }
}
Ответ 3
this обсуждает, почему они добавили эту дополнительную проверку.