Ответ 1
Нет необходимости вызывать оба, потому что this
перенаправляет на другой конструктор, который будет вызывать base
.
Это легко обойти, но мне просто интересно, могу ли я использовать функцию языка или, возможно, тот факт, что язык запрещает это означает, что я делаю логическую ошибку в дизайне классов.
Я делаю самообследование моего кода, чтобы помочь "ожесточить" его для повторного использования, и я просто подошел:
public partial class TrackTyped : Component
{
IContainer components = null;
public TrackTyped()
: base()
{
InitializeComponent();
}
public TrackTyped(IContainer container)
: base()
{
container.Add(this);
InitializeComponent();
}
}
То, что я обычно делаю, когда вижу одну и ту же строку кода в двух конструкторах, это сделать один вызов другим с помощью "this()", но я не могу это сделать.
Если я правильно прочитал spec (я только начал читать спецификацию, чтобы я мог быть не прав):
10.11 Instance Constructors
constructor-declarator:
identifier ( formal-parameter-listopt ) constructor-initializeropt
constructor-initializer:
: base ( argument-listopt )
: this ( argument-listopt )
Это говорит, что у меня может быть только один из них.
ВОПРОС: 10.11 подразумевает, что нет причин для вызова обоих или это просто означает, что язык поддерживает только вызов?
Нет необходимости вызывать оба, потому что this
перенаправляет на другой конструктор, который будет вызывать base
.
Ты не можешь и не можешь. Вы можете перенаправить вызов конструктора другому конструктору того же класса на :this(...)
. Последний конструктор в этой цепочке должен будет инициализировать базу либо неявно, либо явно посредством :base(...)
Предположим, что класс A имеет два конструктора. Один инициализирует базу с помощью :base(2)
, а другой - с помощью :base(3)
. Если первому конструктору было разрешено также указать :this (/*call the other ctor*/)
, как должна быть инициализирована база: с 2 или 3? Вот почему эти вещи не разрешены
Это похоже на то, что вы хотите:
public partial class TrackTyped : Component
{
IContainer components = null;
public TrackTyped()
: base()
{
InitializeComponent();
}
public TrackTyped(IContainer container)
: this()
{
container.Add(this);
}
}
Порядок операторов во втором конструкторе теперь отличается. Если это имеет значение, тогда нет действительно хорошего способа сделать то, что вы хотите, поскольку, хотя у вас есть одна и та же линия, функциональность тонко отличается. В этом случае вам просто нужно повторить одну строку. Не потейте.
И вы правильно читаете спецификацию: она должна быть той или иной.
это то, что вы ищете?
public partial class TrackTyped : Component
{
IContainer components = null;
public TrackTyped() : base()
{
// logic for InitializeComponent() here
}
public TrackTyped(IContainer container) : this()
{
container.Add(this)
}
}
btw: что интересное использование для второго ctor:
var a = TrackTyped(container);
Интересно, удастся ли удалить второй ctor и сделать это? (тот же конечный результат)
container.Add(new TrackTyped());